FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
ObligationCsvImport.php
Go to the documentation of this file.
1 <?php
2 /*
3 Copyright (C) 2014-2017, Siemens AG
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 version 2 as published by the Free Software Foundation.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 
20 
23 
34 {
37  protected $dbManager;
40  protected $delimiter = ',';
43  protected $enclosure = '"';
46  protected $headrow = null;
49  protected $alias = array(
50  'type'=>array('type','Type'),
51  'topic'=>array('topic','Obligation or Risk topic'),
52  'text'=>array('text','Full Text'),
53  'classification'=>array('classification','Classification'),
54  'modifications'=>array('modifications','Apply on modified source code'),
55  'comment'=>array('comment','Comment'),
56  'licnames'=>array('licnames','Associated Licenses'),
57  'candidatenames'=>array('candidatenames','Associated candidate Licenses')
58  );
59 
64  public function __construct(DbManager $dbManager)
65  {
66  $this->dbManager = $dbManager;
67  $this->obligationMap = $GLOBALS['container']->get('businessrules.obligationmap');
68  }
69 
74  public function setDelimiter($delimiter=',')
75  {
76  $this->delimiter = substr($delimiter,0,1);
77  }
78 
83  public function setEnclosure($enclosure='"')
84  {
85  $this->enclosure = substr($enclosure,0,1);
86  }
87 
94  public function handleFile($filename)
95  {
96  if (!is_file($filename) || ($handle = fopen($filename, 'r')) === false) {
97  return _('Internal error');
98  }
99  $cnt = -1;
100  $msg = '';
101  try {
102  while (($row = fgetcsv($handle,0,$this->delimiter,$this->enclosure)) !== false) {
103  $log = $this->handleCsv($row);
104  if (!empty($log)) {
105  $msg .= "$log\n";
106  }
107  $cnt++;
108  }
109  $msg .= _('Read csv').(": $cnt ")._('obligations');
110  } catch(\Exception $e) {
111  fclose($handle);
112  return $msg .= _('Error while parsing file').': '.$e->getMessage();
113  }
114  fclose($handle);
115  return $msg;
116  }
117 
124  private function handleCsv($row)
125  {
126  if ($this->headrow===null) {
127  $this->headrow = $this->handleHeadCsv($row);
128  return 'head okay';
129  }
130 
131  $mRow = array();
132  foreach (array('type','topic','text','classification','modifications','comment','licnames','candidatenames') as $needle) {
133  $mRow[$needle] = $row[$this->headrow[$needle]];
134  }
135 
136  return $this->handleCsvObligation($mRow);
137  }
138 
145  private function handleHeadCsv($row)
146  {
147  $headrow = array();
148  foreach (array('type','topic','text','classification','modifications','comment','licnames','candidatenames') as $needle) {
149  $col = ArrayOperation::multiSearch($this->alias[$needle], $row);
150  if (false === $col) {
151  throw new \Exception("Undetermined position of $needle");
152  }
153  $headrow[$needle] = $col;
154  }
155  return $headrow;
156  }
157 
163  private function getKeyFromTopicAndText($row)
164  {
165  $req = array($row['topic'], $row['text']);
166  $row = $this->dbManager->getSingleRow('SELECT ob_pk FROM obligation_ref WHERE ob_topic=$1 AND ob_md5=md5($2)',$req);
167  return ($row === false) ? false : $row['ob_pk'];
168  }
169 
178  private function compareLicList($exists, $listFromCsv, $candidate, $row)
179  {
180  $getList = $this->obligationMap->getLicenseList($exists, $candidate);
181  $listFromDb = $this->reArrangeString($getList);
182  $listFromCsv = $this->reArrangeString($listFromCsv);
183  $diff = strcmp($listFromDb, $listFromCsv);
184  return $diff;
185  }
186 
193  private function reArrangeString($string)
194  {
195  $string = explode(";", $string);
196  sort($string);
197  $string = implode(",", $string);
198  return $string;
199  }
200 
207  private function clearListFromDb($exists, $candidate)
208  {
209  $licId = 0;
210  $this->obligationMap->unassociateLicenseFromObligation($exists, $licId, $candidate);
211  return true;
212  }
213 
222  private function handleCsvObligation($row)
223  {
224  /* @var $dbManager DbManager */
226  $exists = $this->getKeyFromTopicAndText($row);
227  $associatedLicenses = "";
228  $candidateLicenses = "";
229  $msg = "";
230  if ($exists !== false) {
231  $msg = "Obligation topic '$row[topic]' already exists in DB (id=".$exists."),";
232  if ( $this->compareLicList($exists, $row['licnames'], false, $row) === 0 ) {
233  $msg .=" No Changes in AssociateLicense";
234  } else {
235  $this->clearListFromDb($exists, false);
236  if (!empty($row['licnames'])) {
237  $associatedLicenses .= $this->AssociateWithLicenses($row['licnames'], $exists, false);
238  }
239  $msg .=" Updated AssociatedLicense license";
240  }
241  if ($this->compareLicList($exists, $row['candidatenames'], true, $row) === 0) {
242  $msg .=" No Changes in CandidateLicense";
243  } else {
244  $this->clearListFromDb($exists, true);
245  if (!empty($row['candidatenames'])) {
246  $associatedLicenses .= $this->AssociateWithLicenses($row['candidatenames'], $exists, true);
247  }
248  $msg .=" Updated CandidateLicense";
249  }
250  $this->updateOtherFields($exists, $row);
251  return $msg . "\n" . $associatedLicenses . "\n";
252  }
253 
254  $stmtInsert = __METHOD__.'.insert';
255  $dbManager->prepare($stmtInsert,'INSERT INTO obligation_ref (ob_type,ob_topic,ob_text,ob_classification,ob_modifications,ob_comment,ob_md5)'
256  . ' VALUES ($1,$2,$3,$4,$5,$6,md5($3)) RETURNING ob_pk');
257  $resi = $dbManager->execute($stmtInsert,array($row['type'],$row['topic'],$row['text'],$row['classification'],$row['modifications'],$row['comment']));
258  $new = $dbManager->fetchArray($resi);
259  $dbManager->freeResult($resi);
260 
261  if (!empty($row['licnames'])) {
262  $associatedLicenses .= $this->AssociateWithLicenses($row['licnames'], $new['ob_pk']);
263  }
264  if (!empty($row['candidatenames'])) {
265  $candidateLicenses = $this->AssociateWithLicenses($row['candidatenames'], $new['ob_pk'], true);
266  }
267 
268  $message = "License association results for obligation '$row[topic]':\n";
269  $message .= "$associatedLicenses";
270  $message .= "$candidateLicenses";
271  $message .= "Obligation with id=$new[ob_pk] was added successfully.\n";
272  return $message;
273  }
274 
283  function AssociateWithLicenses($licList, $obPk, $candidate=False)
284  {
285  $associatedLicenses = "";
286  $message = "";
287 
288  $licenses = explode(";",$licList);
289  foreach ($licenses as $license) {
290  $licIds = $this->obligationMap->getIdFromShortname($license, $candidate);
291  $updated = false;
292  if (empty($licIds)) {
293  $message .= "License $license could not be found in the DB.\n";
294  } else {
295  $updated = $this->obligationMap->associateLicenseFromLicenseList($obPk,
296  $licIds, $candidate);
297  }
298  if ($updated) {
299  if ($associatedLicenses == "") {
300  $associatedLicenses = "$license";
301  } else {
302  $associatedLicenses .= ";$license";
303  }
304  }
305  }
306 
307  if (!empty($associatedLicenses)) {
308  $message .= "$associatedLicenses were associated.\n";
309  } else {
310  $message .= "No ";
311  $message .= $candidate ? "candidate": "";
312  $message .= "licenses were associated.\n";
313  }
314  return $message;
315  }
316 
327  function updateOtherFields($exists, $row)
328  {
329  $this->dbManager->getSingleRow('UPDATE obligation_ref SET ob_classification=$2, ob_modifications=$3, ob_comment=$4 where ob_pk=$1',
330  array($exists, $row['classification'], $row['modifications'], $row['comment']),
331  __METHOD__ . '.updateOtherOb');
332  }
333 }
handleFile($filename)
Read the CSV line by line and import it.
Helper class for Obligation CSV Import.
getKeyFromTopicAndText($row)
Get the Obligation key from obligation topic and obligation text.
setEnclosure($enclosure='"')
Update the enclosure.
clearListFromDb($exists, $candidate)
Clear all license maps for given obligation.
Utility functions for specific applications.
AssociateWithLicenses($licList, $obPk, $candidate=False)
Associate selected licenses to the obligation.
updateOtherFields($exists, $row)
Update other fields of the obligation.
compareLicList($exists, $listFromCsv, $candidate, $row)
Compare licenses from Database and CSV.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:28
handleCsvObligation($row)
Handle a single row from CSV.
Fossology exception.
Definition: Exception.php:25
setDelimiter($delimiter=',')
Update the delimiter.