1 : /**********************************************************************
2 : * $Id: writer.cpp 12582 2007-10-29 09:38:21Z pka $
3 : *
4 : * Project: iom - The INTERLIS Object Model
5 : * Purpose: For more information, please see <http://iom.sourceforge.net>
6 : * Author: Claude Eisenhut
7 : *
8 : **********************************************************************
9 : * Copyright (c) 2007, Claude Eisenhut
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 :
31 : /** @file
32 : * adapter to xml writer
33 : * @defgroup writer xml writer functions
34 : * @{
35 : */
36 :
37 :
38 : #include <string.h>
39 :
40 : //#include <xercesc/util/TransService.hpp>
41 : #include <xercesc/framework/XMLFormatter.hpp>
42 : #include <xercesc/framework/LocalFileFormatTarget.hpp>
43 : #include <iom/iom_p.h>
44 : #include <algorithm>
45 : #include <string>
46 :
47 : /** gets the xml representaion of a consistency value.
48 : */
49 0 : static const XMLCh *encodeConsistency(int consistency)
50 : {
51 : const XMLCh *ret;
52 0 : switch(consistency){
53 : case IOM_INCOMPLETE:
54 0 : ret=ustrings::get_INCOMPLETE();
55 0 : break;
56 : case IOM_INCONSISTENT:
57 0 : ret=ustrings::get_INCONSISTENT();
58 0 : break;
59 : case IOM_ADAPTED:
60 0 : ret=ustrings::get_ADAPTED();
61 0 : break;
62 : case IOM_COMPLETE:
63 : default:
64 0 : ret=0;
65 : break;
66 : }
67 0 : return ret;
68 : }
69 :
70 : /** gets the xml representaion of a basket-kind value.
71 : */
72 0 : static const XMLCh *encodeBasketKind(int kind)
73 : {
74 : const XMLCh *ret;
75 0 : switch(kind){
76 : case IOM_UPDATE:
77 0 : ret=ustrings::get_UPDATE();
78 0 : break;
79 : case IOM_INITIAL:
80 0 : ret=ustrings::get_INITIAL();
81 0 : break;
82 : case IOM_FULL:
83 : default:
84 0 : ret=0;
85 : break;
86 : }
87 0 : return ret;
88 : }
89 :
90 : /** gets the xml representaion of a operation value.
91 : */
92 0 : static const XMLCh *encodeOperation(int ops)
93 : {
94 : const XMLCh *ret;
95 0 : switch(ops){
96 : case IOM_OP_UPDATE:
97 0 : ret=ustrings::get_UPDATE();
98 0 : break;
99 : case IOM_OP_DELETE:
100 0 : ret=ustrings::get_DELETE();
101 0 : break;
102 : case IOM_OP_INSERT:
103 : default:
104 0 : ret=0;
105 : break;
106 : }
107 0 : return ret;
108 : }
109 :
110 : /** writes a coord value or a coord segment.
111 : */
112 0 : static void writeCoord(XmlWriter &out, IomObject &obj)
113 : {
114 : /*
115 : object: COORD
116 : C1
117 : 102.0
118 : C2
119 : 402.0
120 : <COORD><C1>102.0</C1><C2>402.0</C2></COORD>
121 : */
122 0 : out.startElement(tags::get_COORD(),0,0);
123 0 : out.startElement(tags::get_C1(),0,0);
124 0 : const XMLCh *c1=obj->getAttrPrim(tags::get_C1(),0);
125 0 : out.characters(c1);
126 0 : out.endElement(/*C1*/);
127 0 : const XMLCh *c2=obj->getAttrPrim(tags::get_C2(),0);
128 0 : if(c2){
129 0 : out.startElement(tags::get_C2(),0,0);
130 0 : out.characters(c2);
131 0 : out.endElement(/*C2*/);
132 0 : const XMLCh *c3=obj->getAttrPrim(tags::get_C3(),0);
133 0 : if(c3){
134 0 : out.startElement(tags::get_C3(),0,0);
135 0 : out.characters(c3);
136 0 : out.endElement(/*C3*/);
137 : }
138 : }
139 0 : out.endElement(/*COORD*/);
140 :
141 0 : }
142 :
143 : /** writes a arc segment value.
144 : */
145 0 : static void writeArc(XmlWriter &out, IomObject &obj)
146 : {
147 : /*
148 : object: ARC
149 : C1
150 : 103.0
151 : C2
152 : 403.0
153 : A1
154 : 104.0
155 : A2
156 : 404.0
157 : <COORD><C1>103.0</C1><C2>403.0</C2><A1>104.0</A1><A2>404.0</A2></COORD>
158 : */
159 0 : out.startElement(tags::get_ARC(),0,0);
160 0 : out.startElement(tags::get_C1(),0,0);
161 0 : const XMLCh *c1=obj->getAttrPrim(tags::get_C1(),0);
162 0 : out.characters(c1);
163 0 : out.endElement(/*C1*/);
164 0 : const XMLCh *c2=obj->getAttrPrim(tags::get_C2(),0);
165 0 : out.startElement(tags::get_C2(),0,0);
166 0 : out.characters(c2);
167 0 : out.endElement(/*C2*/);
168 0 : const XMLCh *c3=obj->getAttrPrim(tags::get_C3(),0);
169 0 : if(c3){
170 0 : out.startElement(tags::get_C3(),0,0);
171 0 : out.characters(c3);
172 0 : out.endElement(/*C3*/);
173 : }
174 0 : const XMLCh *a1=obj->getAttrPrim(tags::get_A1(),0);
175 0 : out.characters(a1);
176 0 : out.endElement(/*A1*/);
177 0 : const XMLCh *a2=obj->getAttrPrim(tags::get_A2(),0);
178 0 : out.startElement(tags::get_A2(),0,0);
179 0 : out.characters(a2);
180 0 : out.endElement(/*A2*/);
181 0 : const XMLCh *r=obj->getAttrPrim(tags::get_R(),0);
182 0 : if(r){
183 0 : out.startElement(tags::get_R(),0,0);
184 0 : out.characters(r);
185 0 : out.endElement(/*R*/);
186 : }
187 0 : out.endElement(/*ARC*/);
188 0 : }
189 :
190 : /** writes a polyline value.
191 : */
192 0 : void iom_file::writePolyline(XmlWriter &out, IomObject &obj,bool hasLineAttr)
193 : {
194 : /*
195 : object: POLYLINE [INCOMPLETE]
196 : lineattr
197 : object: Model.Topic.LineAttr
198 : attr00
199 : 11
200 : sequence // if incomplete; multi sequence values
201 : object: SEGMENTS
202 : segment
203 : object: COORD
204 : C1
205 : 102.0
206 : C2
207 : 402.0
208 : segment
209 : object: ARC
210 : C1
211 : 103.0
212 : C2
213 : 403.0
214 : A1
215 : 104.0
216 : A2
217 : 404.0
218 : segment
219 : object: Model.SplineParam
220 : SegmentEndPoint
221 : object: COORD
222 : C1
223 : 103.0
224 : C2
225 : 403.0
226 : p0
227 : 1.0
228 : p1
229 : 2.0
230 :
231 : <POLYLINE>
232 : <LINEATTR>
233 : <Model.Topic.LineAttr>
234 : <attr00>11</attr00>
235 : </Model.Topic.LineAttr>
236 : </LINEATTR>
237 : <COORD>
238 : <C1>101.0</C1>
239 : <C2>401.0</C2>
240 : </COORD>
241 : <COORD>
242 : <C1>102.0</C1>
243 : <C2>402.0</C2>
244 : </COORD>
245 : <Model.SplineParam>
246 : <SegmentEndPoint>
247 : <COORD>
248 : <C1>103.0</C1>
249 : <C2>403.0</C2>
250 : </COORD>
251 : </SegmentEndPoint>
252 : <p0>1.0</p0>
253 : <p1>2.0</p1>
254 : </Model.SplineParam>
255 : </POLYLINE>
256 : */
257 0 : out.startElement(tags::get_POLYLINE(),0,0);
258 0 : if(hasLineAttr){
259 0 : IomObject lineattr=obj->getAttrObj(tags::get_lineattr(),0);
260 0 : if(!lineattr.isNull()){
261 0 : out.startElement(tags::get_LINEATTR(),0,0);
262 0 : out.startElement(lineattr->getTag(),0,0);
263 0 : writeAttrs(out,lineattr);
264 0 : out.endElement(/*lineattr*/);
265 0 : out.endElement(/*LINEATTR*/);
266 0 : }
267 : }
268 0 : bool clipped=obj->getConsistency()==IOM_INCOMPLETE;
269 0 : for(int sequencei=0;sequencei<obj->getAttrValueCount(tags::get_sequence());sequencei++){
270 0 : if(clipped){
271 0 : out.startElement(tags::get_CLIPPED(),0,0);
272 : }else{
273 : // an unclipped polyline should have only one sequence element
274 0 : if(sequencei>0){
275 0 : iom_issueerr("unclipped polyline with multi 'sequence' elements");
276 0 : break;
277 : }
278 : }
279 0 : IomObject sequence=obj->getAttrObj(tags::get_sequence(),sequencei);
280 0 : for(int segmenti=0;segmenti<sequence->getAttrValueCount(tags::get_segment());segmenti++){
281 0 : IomObject segment=sequence->getAttrObj(tags::get_segment(),segmenti);
282 0 : if(segment->getTag()==tags::get_COORD()){
283 : // COORD
284 0 : writeCoord(out,segment);
285 0 : }else if(segment->getTag()==tags::get_ARC()){
286 : // ARC
287 0 : writeArc(out,segment);
288 : }else{
289 : // custum line form
290 0 : out.startElement(segment->getTag(),0,0);
291 0 : writeAttrs(out,segment);
292 0 : out.endElement(/*segment*/);
293 : }
294 :
295 : }
296 0 : if(clipped){
297 0 : out.endElement(/*CLIPPED*/);
298 : }
299 : }
300 0 : out.endElement(/*POLYLINE*/);
301 0 : }
302 :
303 : /** writes a surface value.
304 : */
305 0 : void iom_file::writeSurface(XmlWriter &out, IomObject &obj)
306 : {
307 : /*
308 : object: MULTISURFACE [INCOMPLETE]
309 : surface // if incomplete; multi surface values
310 : object: SURFACE
311 : boundary
312 : object: BOUNDARY
313 : polyline
314 : object: POLYLINE
315 :
316 :
317 : <SURFACE>
318 : <BOUNDARY>
319 : <POLYLINE .../>
320 : <POLYLINE .../>
321 : </BOUNDARY>
322 : <BOUNDARY>
323 : <POLYLINE .../>
324 : <POLYLINE .../>
325 : </BOUNDARY>
326 : </SURFACE>
327 : */
328 0 : out.startElement(tags::get_SURFACE(),0,0);
329 0 : bool clipped=obj->getConsistency()==IOM_INCOMPLETE;
330 0 : for(int surfacei=0;surfacei<obj->getAttrValueCount(tags::get_surface());surfacei++){
331 0 : if(clipped){
332 0 : out.startElement(tags::get_CLIPPED(),0,0);
333 : }else{
334 : // an unclipped surface should have only one surface element
335 0 : if(surfacei>0){
336 0 : iom_issueerr("unclipped surface with multi 'surface' elements");
337 0 : break;
338 : }
339 : }
340 0 : IomObject surface=obj->getAttrObj(tags::get_surface(),surfacei);
341 0 : for(int boundaryi=0;boundaryi<surface->getAttrValueCount(tags::get_boundary());boundaryi++){
342 0 : IomObject boundary=surface->getAttrObj(tags::get_boundary(),boundaryi);
343 0 : out.startElement(tags::get_BOUNDARY(),0,0);
344 0 : for(int polylinei=0;polylinei<boundary->getAttrValueCount(tags::get_polyline());polylinei++){
345 0 : IomObject polyline=boundary->getAttrObj(tags::get_polyline(),polylinei);
346 0 : writePolyline(out,polyline,true);
347 : }
348 0 : out.endElement(/*BOUNDARY*/);
349 : }
350 0 : if(clipped){
351 0 : out.endElement(/*CLIPPED*/);
352 : }
353 : }
354 0 : out.endElement(/*SURFACE*/);
355 0 : }
356 :
357 0 : void iom_file::writeAttr(XmlWriter &out, IomObject &obj,int attr)
358 : {
359 0 : int valueCount=obj->getAttrValueCount(attr);
360 0 : if(valueCount>0){
361 0 : const XMLCh *val=obj->getAttrPrim(attr,0);
362 : // not a primitive?
363 0 : if(!val){
364 0 : IomObject child=obj->getAttrObj(attr,0);
365 : // some special cases
366 0 : if(child->getTag()==tags::get_COORD()){
367 : // COORD
368 0 : out.startElement(attr,0,0);
369 0 : writeCoord(out,child);
370 0 : out.endElement(/*attr*/);
371 0 : if(valueCount>1){
372 0 : iom_issueerr("max one COORD value allowed");
373 : }
374 0 : }else if(child->getTag()==tags::get_POLYLINE()){
375 : // POLYLINE
376 0 : out.startElement(attr,0,0);
377 0 : writePolyline(out,child,false);
378 0 : out.endElement(/*attr*/);
379 0 : if(valueCount>1){
380 0 : iom_issueerr("max one POLYLINE value allowed");
381 : }
382 0 : }else if(child->getTag()==tags::get_MULTISURFACE()){
383 : // MULTISURFACE
384 0 : out.startElement(attr,0,0);
385 0 : writeSurface(out,child);
386 0 : out.endElement(/*attr*/);
387 0 : if(valueCount>1){
388 0 : iom_issueerr("max one MULTISURFACE value allowed");
389 : }
390 : }else{
391 : // normal case
392 0 : const XMLCh *ref=child->getRefOid();
393 0 : bool isRef= ref ? true : false;
394 : // Reference-attribute or Role or EmbeddedLink?
395 0 : if(isRef){
396 0 : const XMLCh *extref=0;
397 0 : const XMLCh *bid=0;
398 : XMLCh itoabuf[40];
399 0 : const XMLCh *orderpos=0;
400 0 : if(ref){
401 0 : if(child->getRefOrderPos()>0){
402 0 : XMLString::binToText( child->getRefOrderPos(),itoabuf,sizeof(itoabuf)-1,10);
403 0 : orderpos=itoabuf;
404 : }
405 : }
406 0 : bid=child->getRefBid();
407 0 : if(bid){
408 0 : extref=ref;
409 0 : ref=0;
410 : }
411 : XmlWrtAttr refAttr[]={
412 : XmlWrtAttr(ref ? ustrings::get_REF() :0, ref,true)
413 : ,XmlWrtAttr(extref ? ustrings::get_EXTREF() :0, extref,true)
414 : ,XmlWrtAttr(bid ? ustrings::get_BID() :0, bid,true)
415 : ,XmlWrtAttr(orderpos ? ustrings::get_ORDER_POS():0, orderpos)
416 0 : };
417 0 : out.startElement(attr,refAttr,sizeof(refAttr)/sizeof(refAttr[0]));
418 0 : if(child->getAttrCount()>0){
419 0 : out.startElement(child->getTag(),0,0);
420 0 : writeAttrs(out,child);
421 0 : out.endElement(/*child*/);
422 : }
423 0 : out.endElement(/*attr*/);
424 0 : if(valueCount>1){
425 0 : iom_issueerr("max one reference value allowed");
426 : }
427 : }else{
428 : // struct
429 0 : out.startElement(attr,0,0);
430 0 : int valuei=0;
431 0 : while(1){
432 0 : out.startElement(child->getTag(),0,0);
433 0 : writeAttrs(out,child);
434 0 : out.endElement(/*child*/);
435 0 : valuei++;
436 0 : if(valuei>=valueCount){
437 : break;
438 : }
439 0 : child=obj->getAttrObj(attr,valuei);
440 : }
441 0 : out.endElement(/*attr*/);
442 : }
443 0 : }
444 :
445 : }else{
446 0 : out.startElement(attr,0,0);
447 0 : out.characters(val);
448 0 : out.endElement(/*attr*/);
449 0 : if(valueCount>1){
450 0 : iom_issueerr("max one primitive-type value allowed");
451 : }
452 : }
453 : }
454 0 : }
455 :
456 0 : void iom_file::writeAttrs(XmlWriter &out, IomObject &obj)
457 : {
458 0 : tagv_type::iterator tag=tagList.find(obj->getTag());
459 : // class not found?
460 0 : if(tag==tagList.end()){
461 0 : std::string msg="unknown type <";
462 0 : msg+=+obj->getTag_c();
463 0 : msg+=">";
464 0 : iom_issueerr(msg.c_str());
465 : // write all attributes
466 0 : for(int attri=0;attri<obj->getAttrCount();attri++){
467 0 : int attr=obj->getAttrName(attri);
468 0 : writeAttr(out, obj,attr);
469 0 : }
470 : }else{
471 : // class found
472 0 : attrv_type attrv=tag->second;
473 0 : for(attrv_type::size_type attri=0;attri<attrv.size();attri++){
474 0 : int attr=attrv[attri].second;
475 0 : writeAttr(out, obj,attr);
476 0 : }
477 : }
478 0 : }
479 :
480 : /** write all baskets to an xml file.
481 : */
482 0 : int iom_file::save()
483 : {
484 : // build class/attribute list
485 0 : if(ilibasket.isNull()){
486 0 : iom_issueerr("model required to save data");
487 0 : return IOM_ERR_ILLEGALSTATE;
488 : }
489 0 : buildTagList();
490 :
491 : // read rest of file (before we overwrite it!)
492 0 : IomIterator bi=new iom_iterator(this);
493 0 : while(!bi->next_basket().isNull()){
494 : ; // empty
495 : }
496 :
497 : // open file for write
498 0 : XmlWriter out;
499 0 : int ind=0;
500 0 : out.open(filename);out.printNewLine();
501 :
502 : // write header
503 0 : XmlWrtAttr trsfAttr[]={XmlWrtAttr(ustrings::get_xmlns(),ustrings::get_NS_INTERLIS22())};
504 0 : out.printIndent(ind);
505 0 : out.startElement(tags::get_TRANSFER(),trsfAttr,sizeof(trsfAttr)/sizeof(trsfAttr[0]));out.printNewLine();
506 : {
507 0 : ind++;
508 0 : out.printIndent(ind);
509 0 : XStr version("2.2");
510 : XmlWrtAttr headAttr[]={
511 : XmlWrtAttr(ustrings::get_VERSION(),version.unicodeForm())
512 : ,XmlWrtAttr(ustrings::get_SENDER(),getHeadSecSender())
513 0 : };
514 0 : out.startElement(tags::get_HEADERSECTION(),headAttr,sizeof(headAttr)/sizeof(headAttr[0]));out.printNewLine();
515 : {
516 0 : ind++;
517 0 : out.printIndent(ind);
518 0 : out.startElement(tags::get_ALIAS(),0,0);out.printNewLine();
519 : {
520 0 : ind++;
521 0 : ind--;
522 : }
523 0 : out.printIndent(ind);
524 0 : out.endElement(/*ALIAS*/);out.printNewLine();
525 0 : out.printIndent(ind);
526 0 : out.startElement(tags::get_COMMENT(),0,0);
527 0 : out.characters(getHeadSecComment());
528 0 : out.endElement(/*COMMENT*/);out.printNewLine();
529 0 : ind--;
530 : }
531 0 : out.printIndent(ind);
532 0 : out.endElement(/*HEADERSECTION*/);out.printNewLine();
533 0 : ind--;
534 : }
535 :
536 : // write DATASECTION
537 : {
538 0 : ind++;
539 0 : out.printIndent(ind);
540 0 : out.startElement(tags::get_DATASECTION(),0,0);out.printNewLine();
541 : {
542 0 : ind++;
543 :
544 : // write all baskets
545 0 : for(std::vector<IomBasket>::size_type basketi=0;basketi<basketv.size();basketi++){
546 0 : IomBasket basket=basketv.at(basketi);
547 0 : const XMLCh *topics=basket->getTopics();
548 0 : const XMLCh *kind=encodeBasketKind(basket->getKind());
549 0 : const XMLCh *startstate=basket->getKind()!=IOM_FULL ? basket->getStartState() : 0;
550 0 : const XMLCh *endstate=basket->getKind()!=IOM_FULL ? basket->getEndState() : 0;
551 0 : const XMLCh *consistency=encodeConsistency(basket->getConsistency());
552 : XmlWrtAttr basketAttr[]={
553 : XmlWrtAttr(ustrings::get_BID(),basket->getOid(),true)
554 : ,XmlWrtAttr(topics ? ustrings::get_TOPICS():0,topics)
555 : ,XmlWrtAttr(kind ? ustrings::get_KIND():0 ,kind)
556 : ,XmlWrtAttr(startstate ? ustrings::get_STARTSTATE():0,startstate)
557 : ,XmlWrtAttr(endstate ? ustrings::get_ENDSTATE():0,endstate)
558 : ,XmlWrtAttr(consistency ? ustrings::get_CONSISTENCY():0,consistency)
559 0 : };
560 0 : out.printIndent(ind);
561 0 : if(basket->getTag()==0){
562 0 : iom_issueerr("basket requires a TOPIC name");
563 0 : return IOM_ERR_ILLEGALSTATE;
564 : }
565 0 : out.startElement(basket->getTag(),basketAttr,sizeof(basketAttr)/sizeof(basketAttr[0]));out.printNewLine();
566 : {
567 0 : ind++;
568 : // write all objects
569 0 : IomIterator obji=new iom_iterator(basket);
570 0 : IomObject obj=obji->next_object();
571 0 : while(!obj.isNull()){
572 0 : out.printIndent(ind);
573 0 : const XMLCh *bid=obj->getBid();
574 0 : const XMLCh *ops=encodeOperation(obj->getOperation());
575 0 : const XMLCh *consistency=encodeConsistency(basket->getConsistency());
576 : XmlWrtAttr objAttr[]={
577 : XmlWrtAttr(ustrings::get_TID(),obj->getOid(),true)
578 : ,XmlWrtAttr(bid ? ustrings::get_BID():0,bid,true)
579 : ,XmlWrtAttr(ops ? ustrings::get_OPERATION():0 ,ops)
580 : ,XmlWrtAttr(consistency ? ustrings::get_CONSISTENCY():0,consistency)
581 0 : };
582 0 : out.startElement(obj->getTag(),objAttr,sizeof(objAttr)/sizeof(objAttr[0]));
583 0 : writeAttrs(out,obj);
584 0 : out.endElement(/*object*/);out.printNewLine();
585 0 : obj=obji->next_object();
586 : }
587 0 : ind--;
588 : }
589 0 : out.printIndent(ind);
590 0 : out.endElement(/*basket*/);out.printNewLine();
591 : }
592 0 : ind--;
593 : }
594 0 : out.printIndent(ind);
595 0 : out.endElement(/*DATASECTION*/);out.printNewLine();
596 0 : ind--;
597 : }
598 0 : out.printIndent(ind);
599 0 : out.endElement(/*TRANSFER*/);out.printNewLine();
600 : // close file
601 0 : out.close();
602 0 : return 0;
603 : }
604 :
605 0 : int iom_file::getQualifiedTypeName(IomObject &aclass)
606 : {
607 : static const XMLCh period[] =
608 : {
609 : chPeriod, chNull
610 : };
611 0 : IomObject topic=ilibasket->getObject(aclass->getAttrObj(tags::get_container(),0)->getRefOid());
612 0 : IomObject model=ilibasket->getObject(topic->getAttrObj(tags::get_container(),0)->getRefOid());
613 : // class at model level?
614 : XMLCh *qname;
615 0 : if(model->getTag()==tags::get_iom04_metamodel_TransferDescription()){
616 0 : const XMLCh *modelName=topic->getAttrValue(tags::get_name());
617 0 : const XMLCh *className=aclass->getAttrValue(tags::get_name());
618 0 : int qnLen=XMLString::stringLen(modelName)+1+XMLString::stringLen(className)+1;
619 0 : qname=dbgnew XMLCh[qnLen];
620 0 : XMLString::copyString(qname,modelName);
621 0 : XMLString::catString(qname,period);
622 0 : XMLString::catString(qname,className);
623 : }else{
624 0 : const XMLCh *modelName=model->getAttrValue(tags::get_name());
625 0 : const XMLCh *topicName=topic->getAttrValue(tags::get_name());
626 0 : const XMLCh *className=aclass->getAttrValue(tags::get_name());
627 0 : int qnLen=XMLString::stringLen(modelName)+1+XMLString::stringLen(topicName)+1+XMLString::stringLen(className)+1;
628 0 : qname=dbgnew XMLCh[qnLen];
629 0 : XMLString::copyString(qname,modelName);
630 0 : XMLString::catString(qname,period);
631 0 : XMLString::catString(qname,topicName);
632 0 : XMLString::catString(qname,period);
633 0 : XMLString::catString(qname,className);
634 : }
635 0 : int classId=ParserHandler::getTagId(qname);
636 0 : delete[] qname;
637 0 : return classId;
638 : }
639 :
640 0 : void iom_file::buildTagList()
641 : {
642 : // for all links class--(attribute|role)
643 0 : IomIterator obji=new iom_iterator(ilibasket);
644 0 : IomObject obj;
645 0 : while(!(obj=obji->next_object()).isNull()){
646 0 : if(obj->getTag()==tags::get_iom04_metamodel_Table() || obj->getTag()==tags::get_iom04_metamodel_AssociationDef()){
647 : // get qualified name of class
648 0 : int classId=getQualifiedTypeName(obj);
649 : // add to tag list
650 0 : tagv_type::iterator tag=tagList.find(classId);
651 0 : if(tag==tagList.end()){
652 : // not found, add empty attr list
653 0 : attrv_type attrv;
654 0 : tagList[classId]=attrv;
655 : }else{
656 : // found, don't change
657 : }
658 0 : }else if(obj->getTag()==tags::get_iom04_metamodel_ViewableAttributesAndRoles()){
659 : // get class
660 0 : IomObject aclass=ilibasket->getObject(obj->getAttrObj(tags::get_viewable(),0)->getRefOid());
661 : // get qualified name of class
662 0 : int classId=getQualifiedTypeName(aclass);
663 : // get attribute or role
664 0 : IomObject leafref=obj->getAttrObj(tags::get_attributesAndRoles(),0);
665 : // get name
666 0 : IomObject leafele=ilibasket->getObject(leafref->getRefOid());
667 0 : const XMLCh *leafName=leafele->getAttrValue(tags::get_name());
668 0 : int attrId=ParserHandler::getTagId(leafName);
669 : // get element index
670 0 : int eleIdx=leafref->getRefOrderPos()-1;
671 : // add to tag list
672 0 : tagv_type::iterator tag=tagList.find(classId);
673 0 : if(tag==tagList.end()){
674 : // not found, add
675 0 : attrv_type attrv;
676 0 : std::pair<int,int> ele(eleIdx,attrId);
677 0 : attrv.push_back(ele);
678 0 : tagList[classId]=attrv;
679 : }else{
680 : // found, replace
681 0 : attrv_type attrv=tag->second;
682 0 : std::pair<int,int> ele(eleIdx,attrId);
683 0 : attrv.push_back(ele);
684 0 : tagList[classId]=attrv;
685 0 : }
686 : }
687 : }
688 :
689 : // in all classes sort attrs according to pos
690 0 : tagv_type::iterator tag=tagList.begin();
691 0 : for(;tag!=tagList.end();tag++){
692 0 : attrv_type attrv=tag->second;
693 0 : std::sort(attrv.begin(),attrv.end());
694 0 : tagList[tag->first]=attrv;
695 0 : }
696 :
697 0 : }
698 :
699 : /** @}
700 : */
701 :
702 :
703 : //UTF-8
704 : static const XMLCh gUTF8[] =
705 : {
706 : chLatin_U, chLatin_T, chLatin_F, chDash, chDigit_8, chNull
707 : };
708 :
709 : //</
710 : static const XMLCh gEndElement[] =
711 : {
712 : chOpenAngle, chForwardSlash, chNull
713 : };
714 :
715 : //<?xml version="
716 : static const XMLCh gXMLDecl_VersionInfo[] =
717 : {
718 : chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l, chSpace,
719 : chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i, chLatin_o,
720 : chLatin_n, chEqual, chDoubleQuote, chNull
721 : };
722 :
723 : static const XMLCh gXMLDecl_ver10[] =
724 : {
725 : chDigit_1, chPeriod, chDigit_0, chNull
726 : };
727 :
728 : //encoding="
729 : static const XMLCh gXMLDecl_EncodingDecl[] =
730 : {
731 : chLatin_e, chLatin_n, chLatin_c, chLatin_o, chLatin_d, chLatin_i,
732 : chLatin_n, chLatin_g, chEqual, chDoubleQuote, chNull
733 : };
734 :
735 : //"
736 : static const XMLCh gXMLDecl_separator[] =
737 : {
738 : chDoubleQuote, chSpace, chNull
739 : };
740 :
741 : //?>
742 : static const XMLCh gXMLDecl_endtag[] =
743 : {
744 : chQuestion, chCloseAngle, chNull
745 : };
746 :
747 :
748 0 : const XMLCh *XmlWrtAttr::getName()
749 : {
750 0 : return name;
751 : }
752 :
753 0 : const XMLCh *XmlWrtAttr::getValue()
754 : {
755 0 : return value;
756 : }
757 0 : bool XmlWrtAttr::isOid()
758 : {
759 0 : return oidAttr;
760 : }
761 0 : XmlWrtAttr::XmlWrtAttr(const XMLCh *name1,const XMLCh *value1)
762 : : name(name1)
763 : , value(value1)
764 0 : ,oidAttr(false)
765 : {
766 0 : }
767 0 : XmlWrtAttr::XmlWrtAttr(const XMLCh *name1,const XMLCh *value1,bool isOid)
768 : : name(name1)
769 : , value(value1)
770 0 : ,oidAttr(isOid)
771 : {
772 0 : }
773 :
774 0 : void XmlWriter::open(const char *filename)
775 : {
776 : /*
777 : out=fopen("filename","w");
778 : fputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",out);
779 : newline();
780 :
781 : XMLTransService::Codes resCode;
782 : transcoder = XMLPlatformUtils::fgTransService->makeNewTranscoderFor
783 : (
784 : "UTF-8"
785 : , resCode
786 : , 16 * 1024
787 : );
788 : */
789 0 : destination=new LocalFileFormatTarget(filename);
790 : out= new XMLFormatter(gUTF8
791 : ,gXMLDecl_ver10
792 : ,destination
793 : ,XMLFormatter::NoEscapes
794 0 : ,XMLFormatter::UnRep_CharRef);
795 :
796 0 : out->setUnRepFlags(XMLFormatter::UnRep_CharRef);
797 :
798 0 : *out << gXMLDecl_VersionInfo << gXMLDecl_ver10 << gXMLDecl_separator;
799 0 : *out << gXMLDecl_EncodingDecl << gUTF8 << gXMLDecl_separator;
800 0 : *out << gXMLDecl_endtag;
801 0 : }
802 :
803 0 : void XmlWriter::startElement(int tagid,XmlWrtAttr attrv[],int attrc)
804 : {
805 0 : const XMLCh *tagName=ParserHandler::getTagName(tagid);
806 :
807 : *out << XMLFormatter::NoEscapes
808 0 : << chOpenAngle << tagName;
809 :
810 :
811 0 : for(int i=0;i<attrc;i++){
812 0 : if(attrv[i].getName()){
813 : *out << XMLFormatter::NoEscapes
814 : << chSpace << attrv[i].getName()
815 : << chEqual << chDoubleQuote
816 0 : << XMLFormatter::AttrEscapes;
817 0 : if(attrv[i].isOid()){
818 0 : *out << chLatin_x;
819 : }
820 : *out << attrv[i].getValue()
821 : << XMLFormatter::NoEscapes
822 0 : << chDoubleQuote;
823 : }
824 : }
825 :
826 0 : *out << XMLFormatter::NoEscapes << chCloseAngle;
827 0 : stack.push(tagid);
828 0 : }
829 :
830 0 : void XmlWriter::endElement()
831 : {
832 0 : const XMLCh *tagName=ParserHandler::getTagName(stack.top());
833 0 : stack.pop();
834 : *out << XMLFormatter::NoEscapes
835 : << chOpenAngle
836 0 : << chForwardSlash << tagName << chCloseAngle;
837 0 : }
838 :
839 0 : void XmlWriter::characters(const XMLCh *const chars)
840 : {
841 : //fFormatter->setUnRepFlags(XMLFormatter::UnRep_CharRef);
842 0 : out->formatBuf(chars, XMLString::stringLen(chars), XMLFormatter::CharEscapes);
843 0 : }
844 0 : XmlWriter::XmlWriter()
845 : : out(0)
846 0 : , destination(0)
847 : {
848 0 : }
849 0 : XmlWriter::~XmlWriter()
850 : {
851 0 : close();
852 0 : }
853 0 : void XmlWriter::close()
854 : {
855 : //fclose(out);out=0;
856 0 : if(destination){
857 0 : delete destination;destination=0;
858 : }
859 0 : if(out){
860 0 : delete out;out=0;
861 : }
862 0 : }
863 :
864 0 : void XmlWriter::printNewLine()
865 : {
866 : static const XMLCh gEOLSeq[] =
867 : {
868 : chLF, chNull
869 : };
870 0 : *out << gEOLSeq;
871 0 : }
872 :
873 0 : void XmlWriter::printIndent(int level)
874 : {
875 0 : for(int i = 0; i < level; i++)
876 0 : *out << chSpace << chSpace;
877 2139 : }
|