FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
ReuserAgent.php
Go to the documentation of this file.
1 <?php
2 /*
3  Copyright (C) 2014-2018, Siemens AG
4  Author: Daniele Fognini, Andreas Würl
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\Reuser;
21 
35 
36 include_once(__DIR__ . "/version.php");
37 
44 class ReuserAgent extends Agent
45 {
49  private $uploadDao;
69  private $clearingDao;
73  private $decisionTypes;
74 
75  function __construct()
76  {
77  parent::__construct(REUSER_AGENT_NAME, AGENT_VERSION, AGENT_REV);
78  $this->uploadDao = $this->container->get('dao.upload');
79  $this->clearingDao = $this->container->get('dao.clearing');
80  $this->decisionTypes = $this->container->get('decision.types');
81  $this->clearingEventProcessor = $this->container->get('businessrules.clearing_event_processor');
82  $this->clearingDecisionFilter = $this->container->get('businessrules.clearing_decision_filter');
83  $this->clearingDecisionProcessor = $this->container->get('businessrules.clearing_decision_processor');
84  $this->agentLicenseEventProcessor = $this->container->get('businessrules.agent_license_event_processor');
85  }
86 
92  function processUploadId($uploadId)
93  {
94  $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId);
95  foreach ($this->uploadDao->getReusedUpload($uploadId, $this->groupId) as $reuseTriple) {
96  // Get the reuse upload id
97  $reusedUploadId = $reuseTriple['reused_upload_fk'];
98  // Get the group id
99  $reusedGroupId = $reuseTriple['reused_group_fk'];
100  // Get the reuse mode
101  $reuseMode = $reuseTriple['reuse_mode'];
102  // Get the ItemTreeBounds for the upload
103  $itemTreeBoundsReused = $this->uploadDao->getParentItemBounds($reusedUploadId);
104  if (false === $itemTreeBoundsReused) {
105  continue;
106  }
107 
108  if ($reuseMode & UploadDao::REUSE_ENHANCED) {
109  $this->processEnhancedUploadReuse($itemTreeBounds, $itemTreeBoundsReused, $reusedGroupId);
110  } else {
111  $this->processUploadReuse($itemTreeBounds, $itemTreeBoundsReused, $reusedGroupId);
112  }
113 
114  if ($reuseMode & UploadDao::REUSE_MAIN) {
115  $this->reuseMainLicense($uploadId, $this->groupId, $reusedUploadId, $reusedGroupId);
116  }
117 
118  if ($reuseMode & UploadDao::REUSE_CONF) {
119  $this->reuseConfSettings($uploadId, $reusedUploadId);
120  }
121  }
122  return true;
123  }
124  protected function reuseConfSettings($uploadId, $reusedUploadId)
125  {
126  if (!$this->uploadDao->insertReportConfReuse($uploadId, $reusedUploadId)) {
127  echo "INFO :: Report configuration for select upload doesn't exists. Unable to copy!!!";
128  }
129  $this->heartbeat(1);
130  return true;
131  }
142  protected function reuseMainLicense($uploadId, $groupId, $reusedUploadId, $reusedGroupId)
143  {
144  $mainLicenseIds = $this->clearingDao->getMainLicenseIds($reusedUploadId, $reusedGroupId);
145  if (!empty($mainLicenseIds)) {
146  foreach ($mainLicenseIds as $mainLicenseId) {
147  if (in_array($mainLicenseId, $this->clearingDao->getMainLicenseIds($uploadId, $groupId))) {
148  continue;
149  } else {
150  $this->clearingDao->makeMainLicense($uploadId, $groupId, $mainLicenseId);
151  }
152  }
153  }
154  return true;
155  }
156 
165  protected function processUploadReuse($itemTreeBounds, $itemTreeBoundsReused, $reusedGroupId)
166  {
169 
170  $clearingDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBoundsReused, $reusedGroupId);
171  $currenlyVisibleClearingDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBounds, $groupId);
172 
173  $currenlyVisibleClearingDecisionsById = $this->mapByClearingId($currenlyVisibleClearingDecisions);
174  $clearingDecisionsById = $this->mapByClearingId($clearingDecisions);
175 
176  $clearingDecisionsToImport = array_diff_key($clearingDecisionsById,$currenlyVisibleClearingDecisionsById);
177 
178  $clearingDecisionToImportByFileId = $this->mapByFileId($clearingDecisionsToImport);
179 
182  $containedItems = ArrayOperation::callChunked(
183  function ($fileIds) use ($itemTreeBounds, $uploadDao)
184  {
185  return $uploadDao->getContainedItems(
186  $itemTreeBounds,
187  "pfile_fk = ANY($1)",
188  array('{' . implode(', ', $fileIds) . '}')
189  );
190  }, array_keys($clearingDecisionToImportByFileId), 100);
191 
192  foreach ($containedItems as $item) {
193  $fileId = $item->getFileId();
194  if (array_key_exists($fileId, $clearingDecisionToImportByFileId)) {
195  $this->createCopyOfClearingDecision($item->getId(), $userId, $groupId,
196  $clearingDecisionToImportByFileId[$fileId]);
197  } else {
198  throw new \Exception("bad internal state");
199  }
200 
201  $this->heartbeat(1);
202  }
203 
204  return true;
205  }
206 
214  protected function processEnhancedUploadReuse($itemTreeBounds, $itemTreeBoundsReused, $reusedGroupId)
215  {
216  $clearingDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBoundsReused, $reusedGroupId);
217  $currenlyVisibleClearingDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBounds, $this->groupId);
218 
219  $currenlyVisibleClearingDecisionsById = $this->mapByClearingId($currenlyVisibleClearingDecisions);
220  $clearingDecisionsById = $this->mapByClearingId($clearingDecisions);
221 
222  $clearingDecisionsToImport = array_diff_key($clearingDecisionsById,$currenlyVisibleClearingDecisionsById);
223 
224  $sql = "SELECT ut.* FROM uploadtree ur, uploadtree ut WHERE ur.upload_fk=$2"
225  . " AND ur.pfile_fk=$3 AND ut.upload_fk=$1 AND ut.ufile_name=ur.ufile_name";
226  $stmt = __METHOD__.'.reuseByName';
227  $this->dbManager->prepare($stmt, $sql);
228  $treeDao = $this->container->get('dao.tree');
229 
230  foreach ($clearingDecisionsToImport as $clearingDecision) {
231  $reusedPath = $treeDao->getRepoPathOfPfile($clearingDecision->getPfileId());
232 
233  $res = $this->dbManager->execute($stmt,array($itemTreeBounds->getUploadId(),
234  $itemTreeBoundsReused->getUploadId(),$clearingDecision->getPfileId()));
235  while ($row = $this->dbManager->fetchArray($res)) {
236  $newPath = $treeDao->getRepoPathOfPfile($row['pfile_fk']);
237  $this->copyClearingDecisionIfDifferenceIsSmall($reusedPath, $newPath, $clearingDecision, $row['uploadtree_pk']);
238  }
239  $this->dbManager->freeResult($res);
240  }
241  }
242 
254  protected function copyClearingDecisionIfDifferenceIsSmall($reusedPath,$newPath,$clearingDecision,$itemId)
255  {
256  $diffLevel = system("diff $reusedPath $newPath | wc -l");
257  if ($diffLevel === false) {
258  throw new \Exception('cannot use diff tool');
259  }
260  if ($diffLevel < 5) {
261  $this->createCopyOfClearingDecision($itemId, $this->userId, $this->groupId, $clearingDecision);
262  $this->heartbeat(1);
263  }
264  }
265 
273  protected function mapByFileId($clearingDecisions)
274  {
275  $clearingDecisionByFileId = array();
276  foreach ($clearingDecisions as $clearingDecision) {
277  $fileId = $clearingDecision->getPfileId();
278  if (!array_key_exists($fileId, $clearingDecisionByFileId)) {
279  $clearingDecisionByFileId[$fileId] = $clearingDecision;
280  }
281  }
282  return $clearingDecisionByFileId;
283  }
284 
292  protected function createCopyOfClearingDecision($itemId, $userId, $groupId, $clearingDecisionToCopy)
293  {
294  $clearingEventIdsToCopy = array();
296  foreach ($clearingDecisionToCopy->getClearingEvents() as $clearingEvent) {
297  $licenseId = $clearingEvent->getLicenseId();
298  $uploadTreeId = $itemId;
299  $isRemoved = $clearingEvent->isRemoved();
300  $type = ClearingEventTypes::USER;
301  $reportInfo = $clearingEvent->getReportinfo();
302  $comment = $clearingEvent->getComment();
303  $acknowledgement = $clearingEvent->getAcknowledgement();
305  $clearingEventIdsToCopy[] = $this->clearingDao->insertClearingEvent(
306  $uploadTreeId, $userId, $groupId, $licenseId, $isRemoved,
307  $type, $reportInfo, $comment, $acknowledgement, $jobId);
308  }
309 
310  $this->clearingDao->createDecisionFromEvents(
311  $itemId,
312  $userId,
313  $groupId,
314  $clearingDecisionToCopy->getType(),
315  $clearingDecisionToCopy->getScope(),
316  $clearingEventIdsToCopy
317  );
318  }
319 
328  public function mapByClearingId($clearingDecisions)
329  {
330  $mapped = array();
331 
332  foreach ($clearingDecisions as $clearingDecision) {
333  $mapped[$clearingDecision->getClearingId()] = $clearingDecision;
334  }
335 
336  return $mapped;
337  }
338 }
heartbeat($newProcessed)
Send hear beat to the scheduler.
Definition: Agent.php:214
processEnhancedUploadReuse($itemTreeBounds, $itemTreeBoundsReused, $reusedGroupId)
Get clearing decisions and use copyClearingDecisionIfDifferenceIsSmall()
reuseMainLicense($uploadId, $groupId, $reusedUploadId, $reusedGroupId)
Reuse main license from previous upload.
Structure of an Agent with all required parameters.
Definition: Agent.php:51
processUploadId($uploadId)
Get the upload items and reuse based on reuse mode.
Definition: ReuserAgent.php:92
mapByFileId($clearingDecisions)
Maps clearing decisions by file id.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
mapByClearingId($clearingDecisions)
Map clearing decisions by clearing id.
copyClearingDecisionIfDifferenceIsSmall($reusedPath, $newPath, $clearingDecision, $itemId)
Use diff tool to compare files.