1 /*
2 This file is part of dia2code. It generates code from an UML Dia Diagram.
3 Copyright (C) 2000-2014 Javier O'Hara
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
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
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "config.h"
20 
21 #include <iostream>
22 
23 #include "umlClassNode.hpp"
24 #include "umlAttribute.hpp"
25 #include "string2.hpp"
26 #include "parse_diagram.hpp"
27 
umlAttribute()28 umlAttribute::umlAttribute () :
29     name (),
30     value (),
31     type (),
32     comment (),
33     visibility (Visibility::PUBLIC),
34     inheritance (Inheritance::FINAL),
35     isstatic (false),
36     isconstant (false),
37     kind (Kind::UNKNOWN)
38 {
39 }
40 
umlAttribute(std::string name_,std::string value_,std::string type_,std::string comment_,Visibility visibility_,Inheritance inheritance_,bool isstatic_,bool isconstant_,Kind kind_)41 umlAttribute::umlAttribute (std::string name_,
42                             std::string value_,
43                             std::string type_,
44                             std::string comment_,
45                             Visibility visibility_,
46                             Inheritance inheritance_,
47                             bool isstatic_,
48                             bool isconstant_,
49                             Kind kind_) :
50     name (name_),
51     value (value_),
52     type (type_),
53     comment (comment_),
54     visibility (visibility_),
55     inheritance (inheritance_),
56     isstatic (isstatic_),
57     isconstant (isconstant_),
58     kind (kind_)
59 {
60 }
61 
62 const std::string &
getName() const63 umlAttribute::getName () const
64 {
65     return name;
66 }
67 
68 const std::string &
getValue() const69 umlAttribute::getValue () const
70 {
71     return value;
72 }
73 
74 const std::string &
getType() const75 umlAttribute::getType () const
76 {
77     return type;
78 }
79 
80 const std::string &
getComment() const81 umlAttribute::getComment () const
82 {
83     return comment;
84 }
85 
86 const Visibility &
getVisibility() const87 umlAttribute::getVisibility () const
88 {
89     return visibility;
90 }
91 
92 void
setVisibility(Visibility visible)93 umlAttribute::setVisibility (Visibility visible) {
94     visibility = visible;
95 }
96 
97 const Inheritance &
getInheritance() const98 umlAttribute::getInheritance () const
99 {
100     return inheritance;
101 }
102 
103 bool
isStatic() const104 umlAttribute::isStatic () const
105 {
106     return isstatic;
107 }
108 
109 bool
isConstant() const110 umlAttribute::isConstant () const
111 {
112     return isconstant;
113 }
114 
115 Kind
getKind() const116 umlAttribute::getKind () const
117 {
118     return kind;
119 }
120 
121 void
assign(std::string name_,std::string value_,std::string type_,std::string comment_,Visibility visibility_,Inheritance inheritance_,bool isstatic_,bool isconstant_,Kind kind_)122 umlAttribute::assign (std::string name_,
123                       std::string value_,
124                       std::string type_,
125                       std::string comment_,
126                       Visibility visibility_,
127                       Inheritance inheritance_,
128                       bool isstatic_,
129                       bool isconstant_,
130                       Kind kind_)
131 {
132     name = name_;
133     value = value_;
134     type = type_;
135     comment = comment_;
136     visibility = visibility_;
137     inheritance = inheritance_;
138     isstatic = isstatic_ & 1;
139     isconstant = isconstant_ & 1;
140     kind = kind_;
141 }
142 
143 void
check(const umlClassNode & node) const144 umlAttribute::check (const umlClassNode & node) const {
145     if (node.isStereotypeTypedef ()) {
146         if (!name.empty ()) {
147             std::cerr << "Typedef \"" << node.getName () << "\", attribute \""
148                       << name
149                       << "\": ignoring name field in typedef class.\n";
150         }
151     }
152     else {
153         if (name.empty ()) {
154             std::cerr << "Class \"" << node.getName () << "\": an unamed attribute is found.\n";
155         }
156     }
157     if ((!node.isStereotypeEnum ()) && (type.empty ())) {
158         std::cerr << "Class \"" << node.getName () << "\", attribute \""
159                   << name << "\": no type defined.\n";
160     }
161     if ((node.isStereotypeEnum ()) && (visibility != Visibility::PUBLIC)) {
162         std::cerr << "Class \"" << node.getName () << "\", attribute \""
163                   << name << "\": visibility forced to public.\n";
164     }
165 }
166 
167 void
parse(xmlNodePtr node)168 umlAttribute::parse (xmlNodePtr node) {
169     xmlChar *attrval;
170 
171     name.clear ();
172     value.clear ();
173     type.clear ();
174     comment.clear ();
175     visibility = Visibility::PUBLIC;
176     kind = Kind::UNKNOWN;
177     while (node != NULL) {
178         xmlChar *nodename;
179         nodename = xmlGetProp (node, BAD_CAST2 ("name"));
180 
181         if (!strcmp ("name", BAD_TSAC2 (nodename))) {
182             parseDiaNode (node->xmlChildrenNode, name);
183         } else if (!strcmp ("value", BAD_TSAC2 (nodename))) {
184             if (node->xmlChildrenNode->xmlChildrenNode != NULL) {
185                 parseDiaNode (node->xmlChildrenNode, value);
186             }
187         } else if (!strcmp ("type", BAD_TSAC2 (nodename))) {
188             if (node->xmlChildrenNode->xmlChildrenNode != NULL) {
189                 parseDiaNode (node->xmlChildrenNode, type);
190             } else {
191                 type.clear ();
192             }
193         } else if (!strcmp("comment", BAD_TSAC2 (nodename))) {
194             if (node->xmlChildrenNode->xmlChildrenNode != NULL) {
195                parseDiaNode (node->xmlChildrenNode, comment);
196             } else {
197                comment.clear ();
198           }
199         } else if (!strcmp ("kind", BAD_TSAC2 (nodename))) {
200             char tmp;
201             attrval = xmlGetProp (node->xmlChildrenNode, BAD_CAST2 ("val"));
202             tmp = attrval[0];
203             switch (tmp) {
204                 case '0' : {
205                     kind = Kind::UNKNOWN;
206                     break;
207                 }
208                 case '1' : {
209                     kind = Kind::IN;
210                     break;
211                 }
212                 case '2' : {
213                     kind = Kind::OUT;
214                     break;
215                 }
216                 case '3' : {
217                     kind = Kind::IN_OUT;
218                     break;
219                 }
220                 default : {
221                     free (attrval);
222                     throw std::string (std::string ("Unknown kind: ") +
223                                        std::string (1, tmp));
224                 }
225             }
226             free (attrval);
227         } else if (!strcmp ("visibility", BAD_TSAC2 (nodename))) {
228             char tmp;
229             attrval = xmlGetProp (node->xmlChildrenNode, BAD_CAST2 ("val"));
230             tmp = attrval[0];
231             switch (tmp) {
232                 case '0' : {
233                     visibility = Visibility::PUBLIC;
234                     break;
235                 }
236                 case '1' : {
237                     visibility = Visibility::PRIVATE;
238                     break;
239                 }
240                 case '2' : {
241                     visibility = Visibility::PROTECTED;
242                     break;
243                 }
244                 case '3' : {
245                     visibility = Visibility::IMPLEMENTATION;
246                     break;
247                 }
248                 default : {
249                     free (attrval);
250                     throw std::string (std::string ("Unknown visibility: ") +
251                                        std::string (1, tmp));
252                 }
253             }
254             free (attrval);
255         } else if (!strcmp ("inheritance_type", BAD_TSAC2 (nodename))) {
256             char inheritance_tmp;
257             attrval = xmlGetProp (node->xmlChildrenNode, BAD_CAST2 ("val"));
258             inheritance_tmp = attrval[0];
259             switch (inheritance_tmp) {
260                 case '0' : {
261                     inheritance = Inheritance::ABSTRACT;
262                     break;
263                 }
264                 case '1' : {
265                     inheritance = Inheritance::VIRTUAL;
266                     break;
267                 }
268                 case '2' : {
269                     inheritance = Inheritance::FINAL;
270                     break;
271                 }
272                 default : {
273                     free (attrval);
274                     throw std::string (std::string ("Unknown inheritance : ") +
275                                        std::string (1, inheritance_tmp));
276                 }
277             }
278             free (attrval);
279         } else if (!strcmp ("class_scope", BAD_TSAC2 (nodename))) {
280             isstatic = parseBoolean (node->xmlChildrenNode);
281         } else if (!strcmp ("query", BAD_TSAC2 (nodename))) {
282             isconstant = parseBoolean (node->xmlChildrenNode);
283         }
284 
285         free (nodename);
286         node = node->next;
287     }
288 }
289 
290 /**
291   * Inserts "n" into the list "l", in orderly fashion
292 */
293 void
insert(std::list<umlAttribute> & l)294 umlAttribute::insert (std::list <umlAttribute> &l) {
295     l.push_back (*this);
296 /*    std::list <umlAttribute>::iterator itl;
297 
298     itl = l.begin ();
299 
300     if (itl == l.end ()) {
301         l.push_back (*this);
302     }
303     else {
304         while ((itl != l.end ()) && ((*itl).visibility >= visibility)) {
305             ++itl;
306         }
307         if (itl == l.end ()) {
308             l.push_back (*this);
309         }
310         else {
311             l.insert (std::next (itl), *this);
312         }
313     }*/
314 }
315 
~umlAttribute()316 umlAttribute::~umlAttribute ()
317 {
318 }
319 
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
321