1<?php
2/*
3    +-----------------------------------------------------------------------------+
4    | ILIAS open source                                                           |
5    +-----------------------------------------------------------------------------+
6    | Copyright (c) 1998-2001 ILIAS open source, University of Cologne            |
7    |                                                                             |
8    | This program is free software; you can redistribute it and/or               |
9    | modify it under the terms of the GNU General Public License                 |
10    | as published by the Free Software Foundation; either version 2              |
11    | of the License, or (at your option) any later version.                      |
12    |                                                                             |
13    | This program is distributed in the hope that it will be useful,             |
14    | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
15    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
16    | GNU General Public License for more details.                                |
17    |                                                                             |
18    | You should have received a copy of the GNU General Public License           |
19    | along with this program; if not, write to the Free Software                 |
20    | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. |
21    +-----------------------------------------------------------------------------+
22*/
23
24
25/**
26* Abstract meta data sax parser
27* This class should be inherited by all classes that want to parse meta data. E.g ContObjParser, CourseXMLParser ...
28*
29* @author Stefan Meyer <meyer@leifos.com>
30* @version $Id$
31*
32* Inserts Meta data from XML into ILIAS db
33*
34* @extends ilSaxParser
35* @package ilias-core
36*/
37include_once './Services/Xml/classes/class.ilSaxParser.php';
38
39class ilMDSaxParser extends ilSaxParser
40{
41    public $md_in_md = false;
42    public $md_chr_data = '';
43
44    public $md_cur_el = null;
45
46    /*
47     * @var boolean enable/disable parsing status.
48     */
49    public $md_parsing_enabled = null;
50    /*
51     * @var object ilMD
52     */
53    public $md = null;
54
55    /*
56     * @var object ilMDGeneral
57     */
58    public $md_gen;
59
60    /**
61     * @var ilLogger
62     */
63    protected $meta_log;
64
65    /**
66    * Constructor
67    *
68    * @access	public
69    */
70    public function __construct($a_xml_file = '')
71    {
72        global $DIC;
73
74        $lng = $DIC['lng'];
75        $tree = $DIC['tree'];
76
77        $this->meta_log = ilLoggerFactory::getLogger("meta");
78
79
80        // Enable parsing. E.g qpl' s will set this value to false
81        $this->md_parsing_enabled = true;
82
83        parent::__construct($a_xml_file);
84    }
85
86    public function enableMDParsing($a_status)
87    {
88        $this->md_parsing_enabled = (bool) $a_status;
89    }
90    public function getMDParsingStatus()
91    {
92        return (bool) $this->md_parsing_enabled;
93    }
94
95    public function setMDObject(&$md)
96    {
97        $this->md = &$md;
98    }
99    public function &getMDObject()
100    {
101        return is_object($this->md) ? $this->md : false;
102    }
103
104    public function inMetaData()
105    {
106        return $this->md_in_md;
107    }
108
109    /**
110    * set event handlers
111    *
112    * @param	resource	reference to the xml parser
113    * @access	private
114    */
115    public function setHandlers($a_xml_parser)
116    {
117        xml_set_object($a_xml_parser, $this);
118        xml_set_element_handler($a_xml_parser, 'handlerBeginTag', 'handlerEndTag');
119        xml_set_character_data_handler($a_xml_parser, 'handlerCharacterData');
120    }
121
122
123
124    /**
125    * handler for begin of element
126    */
127    public function handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
128    {
129        include_once 'Services/Migration/DBUpdate_5295/classes/class.ilMDLanguageItem.php';
130
131        if (!$this->getMDParsingStatus()) {
132            return;
133        }
134
135        switch ($a_name) {
136            case 'MetaData':
137                $this->md_in_md = true;
138                $this->__pushParent($this->md);
139                break;
140
141            case 'General':
142                $this->md_gen = &$this->md->addGeneral();
143                $this->md_gen->setStructure($a_attribs['Structure']);
144                $this->md_gen->save();
145                $this->__pushParent($this->md_gen);
146                break;
147
148            case 'Identifier':
149                $par = &$this->__getParent();
150                $this->md_ide = &$par->addIdentifier();
151                $this->md_ide->setCatalog($a_attribs['Catalog']);
152                $this->md_ide->setEntry($a_attribs['Entry']);
153                $this->md_ide->save();
154                $this->__pushParent($this->md_ide);
155                break;
156
157            case 'Title':
158                $par = &$this->__getParent();
159                $par->setTitleLanguage(new ilMDLanguageItem($a_attribs['Language']));
160                break;
161
162            case 'Language':
163                $par = &$this->__getParent();
164                $this->md_lan = &$par->addLanguage();
165                $this->md_lan->setLanguage(new ilMDLanguageItem($a_attribs['Language']));
166                $this->md_lan->save();
167                $this->__pushParent($this->md_lan);
168                break;
169
170            case 'Description':
171                $par = &$this->__getParent();
172
173                if (strtolower(get_class($par)) == 'ilmdrights' or
174                   strtolower(get_class($par)) == 'ilmdannotation' or
175                   strtolower(get_class($par)) == 'ilmdclassification') {
176                    $par->setDescriptionLanguage(new ilMDLanguageItem($a_attribs['Language']));
177                    break;
178                } else {
179                    $this->md_des = &$par->addDescription();
180                    $this->md_des->setDescriptionLanguage(new ilMDLanguageItem($a_attribs['Language']));
181                    $this->md_des->save();
182                    $this->__pushParent($this->md_des);
183                    break;
184                }
185
186                // no break
187            case 'Keyword':
188                $par = &$this->__getParent();
189                $this->md_key = &$par->addKeyword();
190                $this->md_key->setKeywordLanguage(new ilMDLanguageItem($a_attribs['Language']));
191                $this->md_key->save();
192                $this->__pushParent($this->md_key);
193                break;
194
195            case 'Coverage':
196                $par = &$this->__getParent();
197                $par->setCoverageLanguage(new ilMDLanguageItem($a_attribs['Language']));
198                break;
199
200            case 'Lifecycle':
201                $par = &$this->__getParent();
202                $this->md_lif = &$par->addLifecycle();
203                $this->md_lif->setStatus($a_attribs['Status']);
204                $this->md_lif->save();
205                $this->__pushParent($this->md_lif);
206                break;
207
208            case 'Version':
209                $par = &$this->__getParent();
210                $par->setVersionLanguage(new ilMDLanguageItem($a_attribs['Language']));
211                break;
212
213            case 'Contribute':
214                $par = &$this->__getParent();
215                $this->md_con = &$par->addContribute();
216                $this->md_con->setRole($a_attribs['Role']);
217                $this->md_con->save();
218                $this->__pushParent($this->md_con);
219                break;
220
221            case 'Entity':
222                $par = &$this->__getParent();
223
224                if (strtolower(get_class($par)) == 'ilmdcontribute') {
225                    $this->md_ent = &$par->addEntity();
226                    $this->md_ent->save();
227                    $this->__pushParent($this->md_ent);
228                    break;
229                } else {
230                    // single element in 'Annotation'
231                    break;
232                }
233                // no break
234            case 'Date':
235                break;
236
237            case 'Meta-Metadata':
238                $par = &$this->__getParent();
239                $this->md_met = &$par->addMetaMetadata();
240                $this->md_met->setMetaDataScheme($a_attribs['MetadataScheme']);
241                $this->md_met->setLanguage(new ilMDLanguageItem($a_attribs['Language']));
242                $this->md_met->save();
243                $this->__pushParent($this->md_met);
244                break;
245
246            case 'Technical':
247                $par = &$this->__getParent();
248                $this->md_tec = &$par->addTechnical();
249                $this->md_tec->save();
250                $this->__pushParent($this->md_tec);
251                break;
252
253            case 'Format':
254                $par = &$this->__getParent();
255                $this->md_for = &$par->addFormat();
256                $this->md_for->save();
257                $this->__pushParent($this->md_for);
258                break;
259
260            case 'Size':
261                break;
262
263            case 'Location':
264                $par = &$this->__getParent();
265                $this->md_loc = &$par->addLocation();
266                $this->md_loc->setLocationType($a_attribs['Type']);
267                $this->md_loc->save();
268                $this->__pushParent($this->md_loc);
269                break;
270
271            case 'Requirement':
272                $par = &$this->__getParent();
273                $this->md_req = &$par->addRequirement();
274                $this->md_req->save();
275                $this->__pushParent($this->md_req);
276                break;
277
278            case 'OrComposite':
279                $par = &$this->__getParent();
280                $this->md_orc = &$par->addOrComposite();
281                $this->__pushParent($this->md_orc);
282                break;
283
284            case 'Type':
285                break;
286
287            case 'OperatingSystem':
288                $par = &$this->__getParent();
289                $par->setOperatingSystemName($a_attribs['Name']);
290                $par->setOperatingSystemMinimumVersion($a_attribs['MinimumVersion']);
291                $par->setOperatingSystemMaximumVersion($a_attribs['MaximumVersion']);
292                break;
293
294            case 'Browser':
295                $par = &$this->__getParent();
296                $par->setBrowserName($a_attribs['Name']);
297                $par->setBrowserMinimumVersion($a_attribs['MinimumVersion']);
298                $par->setBrowserMaximumVersion($a_attribs['MaximumVersion']);
299                break;
300
301            case 'InstallationRemarks':
302                $par = &$this->__getParent();
303                $par->setInstallationRemarksLanguage(new ilMDLanguageItem($a_attribs['Language']));
304                break;
305
306            case 'OtherPlatformRequirements':
307                $par = &$this->__getParent();
308                $par->setOtherPlatformRequirementsLanguage(new ilMDLanguageItem($a_attribs['Language']));
309                break;
310
311            case 'Duration':
312                break;
313
314            case 'Educational':
315                $par = &$this->__getParent();
316                $this->md_edu = &$par->addEducational();
317                $this->md_edu->setInteractivityType($a_attribs['InteractivityType']);
318                $this->md_edu->setLearningResourceType($a_attribs['LearningResourceType']);
319                $this->md_edu->setInteractivityLevel($a_attribs['InteractivityLevel']);
320                $this->md_edu->setSemanticDensity($a_attribs['SemanticDensity']);
321                $this->md_edu->setIntendedEndUserRole($a_attribs['IntendedEndUserRole']);
322                $this->md_edu->setContext($a_attribs['Context']);
323                $this->md_edu->setDifficulty($a_attribs['Difficulty']);
324                $this->md_edu->save();
325                $this->__pushParent($this->md_edu);
326                break;
327
328            case 'TypicalAgeRange':
329                $par = &$this->__getParent();
330                $this->md_typ = &$par->addTypicalAgeRange();
331                $this->md_typ->setTypicalAgeRangeLanguage(new ilMDLanguageItem($a_attribs['Language']));
332                $this->md_typ->save();
333                $this->__pushParent($this->md_typ);
334                break;
335
336            case 'TypicalLearningTime':
337                break;
338
339            case 'Rights':
340                $par = &$this->__getParent();
341                $this->md_rig = &$par->addRights();
342                $this->md_rig->setCosts($a_attribs['Cost']);
343                $this->md_rig->setCopyrightAndOtherRestrictions($a_attribs['CopyrightAndOtherRestrictions']);
344                $this->md_rig->save();
345                $this->__pushParent($this->md_rig);
346                break;
347
348            case 'Relation':
349                $par = &$this->__getParent();
350                $this->md_rel = &$par->addRelation();
351                $this->md_rel->setKind($a_attribs['Kind']);
352                $this->md_rel->save();
353                $this->__pushParent($this->md_rel);
354                break;
355
356            case 'Resource':
357                break;
358
359            case 'Identifier_':
360                $par = &$this->__getParent();
361                $this->md_ide_ = &$par->addIdentifier_();
362                $this->md_ide_->setCatalog($a_attribs['Catalog']);
363                $this->md_ide_->setEntry($a_attribs['Entry']);
364                $this->md_ide_->save();
365                $this->__pushParent($this->md_ide_);
366                break;
367
368            case 'Annotation':
369                $par = &$this->__getParent();
370                $this->md_ann = &$par->addAnnotation();
371                $this->md_ann->save();
372                $this->__pushParent($this->md_ann);
373                break;
374
375            case 'Classification':
376                $par = &$this->__getParent();
377                $this->md_cla = &$par->addClassification();
378                $this->md_cla->setPurpose($a_attribs['Purpose']);
379                $this->md_cla->save();
380                $this->__pushParent($this->md_cla);
381                break;
382
383            case 'TaxonPath':
384                $par = &$this->__getParent();
385                $this->md_taxp = &$par->addTaxonPath();
386                $this->md_taxp->save();
387                $this->__pushParent($this->md_taxp);
388                break;
389
390            case 'Source':
391                $par = &$this->__getParent();
392                $par->setSourceLanguage(new ilMDLanguageItem($a_attribs['Language']));
393                break;
394
395            case 'Taxon':
396                $par = &$this->__getParent();
397                $this->md_tax = &$par->addTaxon();
398                $this->md_tax->setTaxonLanguage(new ilMDLanguageItem($a_attribs['Language']));
399                $this->md_tax->setTaxonId($a_attribs['Id']);
400                $this->md_tax->save();
401                $this->__pushParent($this->md_tax);
402                break;
403        }
404    }
405
406    /**
407    * handler for end of element
408    */
409    public function handlerEndTag($a_xml_parser, $a_name)
410    {
411        if (!$this->getMDParsingStatus()) {
412            return;
413        }
414
415        switch ($a_name) {
416            case 'MetaData':
417                $this->md_parent = array();
418                $this->md_in_md = false;
419                break;
420
421            case 'General':
422                $par = &$this->__getParent();
423                $par->update();
424                $this->__popParent();
425                break;
426
427            case 'Identifier':
428                $par = &$this->__getParent();
429                $par->update();
430                $this->__popParent();
431                break;
432
433            case 'Title':
434                $par = &$this->__getParent();
435                $par->setTitle($this->__getCharacterData());
436                break;
437
438            case 'Language':
439                $par = &$this->__getParent();
440                $par->update();
441                $this->__popParent();
442                break;
443
444            case 'Description':
445                $par = &$this->__getParent();
446                if (strtolower(get_class($par)) == 'ilmddescription') {
447                    $par->setDescription($this->__getCharacterData());
448                    $par->update();
449                    $this->__popParent();
450                    break;
451                } else {
452                    $par->setDescription($this->__getCharacterData());
453                    break;
454                }
455
456                // no break
457            case 'Keyword':
458                $par = &$this->__getParent();
459                $par->setKeyword($this->__getCharacterData());
460                $this->meta_log->debug("Keyword: " . $this->__getCharacterData());
461                $par->update();
462                $this->__popParent();
463                break;
464
465            case 'Coverage':
466                $par = &$this->__getParent();
467                $par->setCoverage($this->__getCharacterData());
468                break;
469
470            case 'Lifecycle':
471                $par = &$this->__getParent();
472                $par->update();
473                $this->__popParent();
474                break;
475
476            case 'Version':
477                $par = &$this->__getParent();
478                $par->setVersion($this->__getCharacterData());
479                break;
480
481            case 'Contribute':
482                $par = &$this->__getParent();
483                $par->update();
484                $this->__popParent();
485                break;
486
487            case 'Entity':
488                $par = &$this->__getParent();
489
490                if (strtolower(get_class($par)) == 'ilmdentity') {
491                    $par->setEntity($this->__getCharacterData());
492                    $par->update();
493                    $this->__popParent();
494                } else {
495                    // Single element in 'Annotation'
496                    $par->setEntity($this->__getCharacterData());
497                }
498                break;
499
500            case 'Date':
501                $par = &$this->__getParent();
502                $par->setDate($this->__getCharacterData());
503                break;
504
505            case 'Meta-Metadata':
506                $par = &$this->__getParent();
507                $par->update();
508                $this->__popParent();
509                break;
510
511            case 'Technical':
512                $par = &$this->__getParent();
513                $par->update();
514                $this->__popParent();
515                break;
516
517            case 'Format':
518                $par = &$this->__getParent();
519                $par->setFormat($this->__getCharacterData());
520                $par->update();
521                $this->__popParent();
522                break;
523
524            case 'Size':
525                $par = &$this->__getParent();
526                $par->setSize($this->__getCharacterData());
527                break;
528
529            case 'Location':
530                $par = &$this->__getParent();
531                $par->setLocation($this->__getCharacterData());
532                $par->update();
533                $this->__popParent();
534                break;
535
536            case 'Requirement':
537                $par = &$this->__getParent();
538                $par->update();
539                $this->__popParent();
540                break;
541
542            case 'OrComposite':
543                $this->__popParent();
544                break;
545
546            case 'Type':
547                break;
548
549            case 'OperatingSystem':
550                break;
551
552            case 'Browser':
553                break;
554
555            case 'InstallationRemarks':
556                $par = &$this->__getParent();
557                $par->setInstallationRemarks($this->__getCharacterData());
558                break;
559
560            case 'OtherPlatformRequirements':
561                $par = &$this->__getParent();
562                $par->setOtherPlatformRequirements($this->__getCharacterData());
563                break;
564
565            case 'Duration':
566                $par = &$this->__getParent();
567                $par->setDuration($this->__getCharacterData());
568                break;
569
570            case 'Educational':
571                $par = &$this->__getParent();
572                $par->update();
573                $this->__popParent();
574                break;
575
576            case 'TypicalAgeRange':
577                $par = &$this->__getParent();
578                $par->setTypicalAgeRange($this->__getCharacterData());
579                $par->update();
580                $this->__popParent();
581                break;
582
583            case 'TypicalLearningTime':
584                $par = &$this->__getParent();
585                $par->setTypicalLearningTime($this->__getCharacterData());
586                break;
587
588            case 'Rights':
589                $par = &$this->__getParent();
590                $par->update();
591                $this->__popParent();
592                break;
593
594            case 'Relation':
595                $par = &$this->__getParent();
596                $par->update();
597                $this->__popParent();
598                break;
599
600            case 'Resource':
601                break;
602
603            case 'Identifier_':
604                $par = &$this->__getParent();
605                $par->update();
606                $this->__popParent();
607                break;
608
609            case 'Annotation':
610                $par = &$this->__getParent();
611                $par->update();
612                $this->__popParent();
613                break;
614
615            case 'Classification':
616                $par = &$this->__getParent();
617                $par->update();
618                $this->__popParent();
619                break;
620
621            case 'TaxonPath':
622                $par = &$this->__getParent();
623                $par->update();
624                $this->__popParent();
625                break;
626
627            case 'Taxon':
628                $par = &$this->__getParent();
629                $par->setTaxon($this->__getCharacterData());
630                $par->update();
631                $this->__popParent();
632                break;
633
634            case 'Source':
635                $par = &$this->__getParent();
636                $par->setSource($this->__getCharacterData());
637                break;
638
639        }
640        $this->md_chr_data = '';
641    }
642
643    /**
644    * handler for character data
645    */
646    public function handlerCharacterData($a_xml_parser, $a_data)
647    {
648        if (!$this->getMDParsingStatus()) {
649            return;
650        }
651
652        if ($this->inMetaData() and $a_data != "\n") {
653            // Replace multiple tabs with one space
654            $a_data = preg_replace("/\t+/", " ", $a_data);
655
656            $this->md_chr_data .= $a_data;
657        }
658    }
659
660
661
662    // PRIVATE
663    public function __getCharacterData()
664    {
665        return trim($this->md_chr_data);
666    }
667
668    public function __pushParent(&$md_obj)
669    {
670        $this->md_parent[] = &$md_obj;
671        #echo '<br />';
672        foreach ($this->md_parent as $class) {
673            #echo get_class($class).' -> ';
674        }
675    }
676    public function &__popParent()
677    {
678        $class = array_pop($this->md_parent);
679        unset($class);
680        #echo '<br />DELETE '.get_class($class);
681    }
682    public function &__getParent()
683    {
684        return $this->md_parent[count($this->md_parent) - 1];
685    }
686}
687