blob: b5708a6960e055c0ebff4deca059bb2babe45521 [file] [log] [blame]
david_williams96213482004-11-11 09:07:12 +00001/*******************************************************************************
2 * Copyright (c) 2001, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Jens Lukowski/Innoopract - initial renaming/restructuring
11 *
12 *******************************************************************************/
13package org.eclipse.wst.xml.core.internal.document;
14
15
16
david_williams56777022005-04-11 06:21:55 +000017import org.eclipse.wst.xml.core.internal.commentelement.impl.CommentElementRegistry;
david_williamsc06c86f2005-03-18 18:23:41 +000018import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
19import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
david_williams4ad020f2005-04-18 08:00:30 +000020import org.eclipse.wst.xml.core.internal.provisional.IXMLCharEntity;
21import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
22import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
23import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
24import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
25import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator;
david_williams96213482004-11-11 09:07:12 +000026import org.w3c.dom.Attr;
27import org.w3c.dom.CDATASection;
28import org.w3c.dom.Comment;
29import org.w3c.dom.DocumentType;
30import org.w3c.dom.Element;
31import org.w3c.dom.EntityReference;
32import org.w3c.dom.NamedNodeMap;
33import org.w3c.dom.Node;
34import org.w3c.dom.ProcessingInstruction;
35import org.w3c.dom.Text;
36
37
38/**
39 */
david_williams6a8e3892005-04-05 05:21:12 +000040public class XMLGeneratorImpl implements ISourceGenerator {
david_williams96213482004-11-11 09:07:12 +000041 private static final String CDATA_CLOSE = "]]>";//$NON-NLS-1$
42 private static final String CDATA_OPEN = "<![CDATA[";//$NON-NLS-1$
43 private static final String COMMENT_CLOSE = "-->";//$NON-NLS-1$
44 private static final String COMMENT_OPEN = "<!--";//$NON-NLS-1$
45 private static final String DOCTYPE_OPEN = "<!DOCTYPE";//$NON-NLS-1$
46 private static final String EMPTY_CLOSE = " />";//$NON-NLS-1$
47 private static final String END_OPEN = "</";//$NON-NLS-1$
48
49 private static XMLGeneratorImpl instance = null;
50 private static final String PI_CLOSE = "?>";//$NON-NLS-1$
51 private static final String PI_OPEN = "<?";//$NON-NLS-1$
52 private static final String PUBLIC_ID = "PUBLIC";//$NON-NLS-1$
53 private static final String SSI_PREFIX = "ssi";//$NON-NLS-1$
54 //private static final String SSI_FEATURE = "SSI";//$NON-NLS-1$
55 private static final String SSI_TOKEN = "#";//$NON-NLS-1$
56 private static final String SYSTEM_ID = "SYSTEM";//$NON-NLS-1$
57 private static final String TAG_CLOSE = ">";//$NON-NLS-1$
58
59 /**
60 */
david_williams6a8e3892005-04-05 05:21:12 +000061 public synchronized static ISourceGenerator getInstance() {
david_williams96213482004-11-11 09:07:12 +000062 if (instance == null)
63 instance = new XMLGeneratorImpl();
64 return instance;
65 }
66
67 /**
68 */
69 //private boolean isCommentTag(XMLElement element) {
70 // if (element == null) return false;
71 // DocumentImpl document = (DocumentImpl)element.getOwnerDocument();
72 // if (document == null) return false;
73 // DocumentTypeAdapter adapter = document.getDocumentTypeAdapter();
74 // if (adapter == null) return false;
75 // if (!adapter.hasFeature(SSI_FEATURE)) return false;
76 // String prefix = element.getPrefix();
77 // return (prefix != null && prefix.equals(SSI_PREFIX));
78 //}
79 /**
80 * Helper to modify the tag name in sub-classes
81 */
82 private static void setTagName(Element element, String tagName) {
83 if (element == null || tagName == null)
84 return;
85 ((ElementImpl) element).setTagName(tagName);
86 }
87
88 /**
89 * XMLModelGenerator constructor
90 */
91 private XMLGeneratorImpl() {
92 super();
93 }
94
95 /**
96 */
97 public String generateAttrName(Attr attr) {
98 if (attr == null)
99 return null;
100 String attrName = attr.getName();
101 if (attrName == null)
102 return null;
103 if (attrName.startsWith(JSPTag.TAG_OPEN)) {
104 if (!attrName.endsWith(JSPTag.TAG_CLOSE)) {
105 // close JSP
106 return (attrName + JSPTag.TAG_CLOSE);
107 }
108 }
david_williamsc39caaf2005-04-05 06:07:16 +0000109 if (((IDOMAttr) attr).isGlobalAttr() && CMNodeUtil.getAttributeDeclaration(attr) != null) {
david_williams96213482004-11-11 09:07:12 +0000110 switch (getAttrNameCase(attr)) {
111 case DocumentTypeAdapter.UPPER_CASE :
112 attrName = attrName.toUpperCase();
113 break;
114 case DocumentTypeAdapter.LOWER_CASE :
115 attrName = attrName.toLowerCase();
116 break;
117 default :
118 // ASIS_CASE
119 break;
120 }
121 }
122 return attrName;
123 }
124
125 /**
126 */
127 public String generateAttrValue(Attr attr) {
128 return generateAttrValue(attr, (char) 0); // no quote preference
129 }
130
131 /**
132 */
133 public String generateAttrValue(Attr attr, char quote) {
134 if (attr == null)
135 return null;
136 String name = attr.getName();
137 SourceValidator validator = new SourceValidator(attr);
david_williamsc39caaf2005-04-05 06:07:16 +0000138 String value = validator.convertSource(((IDOMNode) attr).getValueSource());
david_williams96213482004-11-11 09:07:12 +0000139 if (value == null || value.length() == 0) {
140 if (name != null && name.startsWith(JSPTag.TAG_OPEN))
141 return null;
142 if (isBooleanAttr(attr)) {
143 if (((AttrImpl) attr).isXMLAttr()) {
144 // generate the name as value
145 value = attr.getName();
146 } else {
147 // not to generate '=' and value for HTML boolean
148 return null;
149 }
150 }
151 }
152 return generateAttrValue(value, quote);
153 }
154
155 /**
156 */
157 public String generateAttrValue(String value, char quote) {
158 // assume the valid is already validated not to include both quotes
159 if (quote == '"') {
160 if ((value != null) && (value.indexOf('"') >= 0))
161 quote = '\''; // force
162 } else if (quote == '\'') {
163 if ((value != null) && (value.indexOf('\'') >= 0))
164 quote = '"'; // force
165 } else { // no preference
166 if ((value != null) && (value.indexOf('"') < 0))
167 quote = '"';
168 else
169 quote = '\'';
170 }
171
172 int length = (value == null ? 0 : value.length());
173 StringBuffer buffer = new StringBuffer(length + 2);
174 buffer.append(quote);
175 if (value != null)
176 buffer.append(value);
177 buffer.append(quote);
178 return buffer.toString();
179 }
180
181 /**
182 * generateCDATASection method
183 *
184 * @return java.lang.String
185 * @param comment
186 * org.w3c.dom.CDATASection
187 */
188 public String generateCDATASection(CDATASection cdata) {
189 if (cdata == null)
190 return null;
191
192 String data = cdata.getData();
193 int length = (data != null ? data.length() : 0);
194 StringBuffer buffer = new StringBuffer(length + 16);
195 buffer.append(CDATA_OPEN);
196 if (data != null)
197 buffer.append(data);
198 buffer.append(CDATA_CLOSE);
199 return buffer.toString();
200 }
201
202 /**
203 * generateChild method
204 *
205 * @return java.lang.String
206 * @param org.w3c.dom.Node
207 */
208 public String generateChild(Node parentNode) {
209 if (parentNode == null)
210 return null;
211 if (!parentNode.hasChildNodes())
212 return null;
213
214 StringBuffer buffer = new StringBuffer();
215 for (Node child = parentNode.getFirstChild(); child != null; child = child.getNextSibling()) {
216 String childSource = generateSource(child);
217 if (childSource != null)
218 buffer.append(childSource);
219 }
220 return buffer.toString();
221 }
222
223 /**
224 */
225 public String generateCloseTag(Node node) {
226 if (node == null)
227 return null;
228
229 switch (node.getNodeType()) {
230 case Node.ELEMENT_NODE : {
231 ElementImpl element = (ElementImpl) node;
232 if (element.isCommentTag()) {
233 if (element.isJSPTag())
234 return JSPTag.COMMENT_CLOSE;
235 return COMMENT_CLOSE;
236 }
237 if (element.isJSPTag())
238 return JSPTag.TAG_CLOSE;
239 if (element.isEmptyTag())
240 return EMPTY_CLOSE;
241 return TAG_CLOSE;
242 }
243 case Node.COMMENT_NODE : {
244 CommentImpl comment = (CommentImpl) node;
245 if (comment.isJSPTag())
246 return JSPTag.COMMENT_CLOSE;
247 return COMMENT_CLOSE;
248 }
249 case Node.DOCUMENT_TYPE_NODE :
250 return TAG_CLOSE;
251 case Node.PROCESSING_INSTRUCTION_NODE :
252 return PI_CLOSE;
253 case Node.CDATA_SECTION_NODE :
254 return CDATA_CLOSE;
255 default :
256 break;
257 }
258
259 return null;
260 }
261
262 /**
263 * generateComment method
264 *
265 * @return java.lang.String
266 * @param comment
267 * org.w3c.dom.Comment
268 */
269 public String generateComment(Comment comment) {
270 if (comment == null)
271 return null;
272
273 String data = comment.getData();
274 int length = (data != null ? data.length() : 0);
275 StringBuffer buffer = new StringBuffer(length + 8);
276 CommentImpl impl = (CommentImpl) comment;
277 if (!impl.isJSPTag())
278 buffer.append(COMMENT_OPEN);
279 else
280 buffer.append(JSPTag.COMMENT_OPEN);
281 if (data != null)
282 buffer.append(data);
283 if (!impl.isJSPTag())
284 buffer.append(COMMENT_CLOSE);
285 else
286 buffer.append(JSPTag.COMMENT_CLOSE);
287 return buffer.toString();
288 }
289
290 /**
291 * generateDoctype method
292 *
293 * @return java.lang.String
294 * @param docType
295 * org.w3c.dom.DocumentType
296 */
297 public String generateDoctype(DocumentType docType) {
298 if (docType == null)
299 return null;
300
301 String name = docType.getName();
302 int length = (name != null ? name.length() : 0);
303 StringBuffer buffer = new StringBuffer(length + 16);
304 buffer.append(DOCTYPE_OPEN);
305 buffer.append(' ');
306 if (name != null)
307 buffer.append(name);
308 DocumentTypeImpl dt = (DocumentTypeImpl) docType;
309 String publicID = dt.getPublicId();
310 String systemID = dt.getSystemId();
311 if (publicID != null) {
312 buffer.append(' ');
313 buffer.append(PUBLIC_ID);
314 buffer.append(' ');
315 buffer.append('"');
316 buffer.append(publicID);
317 buffer.append('"');
318 if (systemID != null) {
319 buffer.append(' ');
320 buffer.append('"');
321 buffer.append(systemID);
322 buffer.append('"');
323 }
324 } else {
325 if (systemID != null) {
326 buffer.append(' ');
327 buffer.append(SYSTEM_ID);
328 buffer.append(' ');
329 buffer.append('"');
330 buffer.append(systemID);
331 buffer.append('"');
332 }
333 }
334 buffer.append('>');
335 return buffer.toString();
336 }
337
338 /**
339 * generateElement method
340 *
341 * @return java.lang.String
342 * @param element
343 * Element
344 */
345 public String generateElement(Element element) {
346 if (element == null)
347 return null;
348
349 // if empty tag is preferrable, generate as empty tag
350 ElementImpl impl = (ElementImpl) element;
351 if (impl.preferEmptyTag())
352 impl.setEmptyTag(true);
353
354 StringBuffer buffer = new StringBuffer();
355 String startTag = generateStartTag(element);
356 if (startTag != null)
357 buffer.append(startTag);
358 String child = generateChild(element);
359 if (child != null)
360 buffer.append(child);
361 String endTag = generateEndTag(element);
362 if (endTag != null)
363 buffer.append(endTag);
364 return buffer.toString();
365 }
366
367 /**
368 * generateEndTag method
369 *
370 * @return java.lang.String
371 * @param element
372 * org.w3c.dom.Element
373 */
374 public String generateEndTag(Element element) {
375 if (element == null)
376 return null;
377
378 ElementImpl impl = (ElementImpl) element;
379
380 // first check if tag adapter exists
381 TagAdapter adapter = (TagAdapter) impl.getExistingAdapter(TagAdapter.class);
382 if (adapter != null) {
383 String endTag = adapter.getEndTag(impl);
384 if (endTag != null)
385 return endTag;
386 }
387
388 if (impl.isEmptyTag())
389 return null;
390 if (!impl.isContainer())
391 return null;
392 if (impl.isJSPTag())
393 return JSPTag.TAG_CLOSE;
394
395 String tagName = generateTagName(element);
396 int length = (tagName != null ? tagName.length() : 0);
397 StringBuffer buffer = new StringBuffer(length + 4);
398 buffer.append(END_OPEN);
399 if (tagName != null)
400 buffer.append(tagName);
401 buffer.append('>');
402 return buffer.toString();
403 }
404
405 /**
406 * generateEntityRef method
407 *
408 * @return java.lang.String
409 * @param entityRef
410 * org.w3c.dom.EntityReference
411 */
412 public String generateEntityRef(EntityReference entityRef) {
413 if (entityRef == null)
414 return null;
415
416 String name = entityRef.getNodeName();
417 int length = (name != null ? name.length() : 0);
418 StringBuffer buffer = new StringBuffer(length + 4);
419 buffer.append('&');
420 if (name != null)
421 buffer.append(name);
422 buffer.append(';');
423 return buffer.toString();
424 }
425
426 /**
427 * generatePI method
428 *
429 * @return java.lang.String
430 * @param pi
431 * org.w3c.dom.ProcessingInstruction
432 */
433 public String generatePI(ProcessingInstruction pi) {
434 if (pi == null)
435 return null;
436
437 String target = pi.getTarget();
438 String data = pi.getData();
439 int length = (target != null ? target.length() : 0);
440 if (data != null)
441 length += data.length();
442 StringBuffer buffer = new StringBuffer(length + 8);
443 buffer.append(PI_OPEN);
444 if (target != null)
445 buffer.append(target);
446 buffer.append(' ');
447 if (data != null)
448 buffer.append(data);
449 buffer.append(PI_CLOSE);
450 return buffer.toString();
451 }
452
453 /**
454 * generateSource method
455 *
456 * @return java.lang.String
457 * @param node
458 * org.w3c.dom.Node
459 */
460 public String generateSource(Node node) {
461 switch (node.getNodeType()) {
462 case Node.ELEMENT_NODE :
463 return generateElement((Element) node);
464 case Node.TEXT_NODE :
465 return generateText((Text) node);
466 case Node.COMMENT_NODE :
467 return generateComment((Comment) node);
468 case Node.DOCUMENT_TYPE_NODE :
469 return generateDoctype((DocumentType) node);
470 case Node.PROCESSING_INSTRUCTION_NODE :
471 return generatePI((ProcessingInstruction) node);
472 case Node.CDATA_SECTION_NODE :
473 return generateCDATASection((CDATASection) node);
474 case Node.ENTITY_REFERENCE_NODE :
475 return generateEntityRef((EntityReference) node);
476 default :
477 // DOCUMENT
478 break;
479 }
480 return generateChild(node);
481 }
482
483 /**
484 * generateStartTag method
485 *
486 * @return java.lang.String
487 * @param element
488 * Element
489 */
490 public String generateStartTag(Element element) {
491 if (element == null)
492 return null;
493
494 ElementImpl impl = (ElementImpl) element;
495
496 if (impl.isJSPTag()) {
497 // check if JSP content type and JSP Document
david_williamsc39caaf2005-04-05 06:07:16 +0000498 IDOMDocument document = (IDOMDocument) element.getOwnerDocument();
david_williams96213482004-11-11 09:07:12 +0000499 if (document != null && document.isJSPType()) {
500 if (document.isJSPDocument() && !impl.hasChildNodes()) {
501 impl.setJSPTag(false);
502 }
503 } else {
504 impl.setJSPTag(false);
505 }
506 }
507 if (impl.isCommentTag() && impl.getExistingAdapter(TagAdapter.class) == null) {
508 CommentElementRegistry registry = CommentElementRegistry.getInstance();
509 registry.setupCommentElement(impl);
510 }
511
512 // first check if tag adapter exists
513 TagAdapter adapter = (TagAdapter) impl.getExistingAdapter(TagAdapter.class);
514 if (adapter != null) {
515 String startTag = adapter.getStartTag(impl);
516 if (startTag != null)
517 return startTag;
518 }
519
520 StringBuffer buffer = new StringBuffer();
521
522 if (impl.isCommentTag()) {
523 if (impl.isJSPTag())
524 buffer.append(JSPTag.COMMENT_OPEN);
525 else
526 buffer.append(COMMENT_OPEN);
527 String tagName = generateTagName(element);
528 if (tagName != null)
529 buffer.append(tagName);
530 } else if (impl.isJSPTag()) {
531 buffer.append(JSPTag.TAG_OPEN);
532 String tagName = generateTagName(element);
533 if (tagName != null)
534 buffer.append(tagName);
535 if (impl.isContainer())
536 return buffer.toString(); // JSP container
537 } else {
538 buffer.append('<');
539 String tagName = generateTagName(element);
540 if (tagName != null)
541 buffer.append(tagName);
542 }
543
544 NamedNodeMap attributes = element.getAttributes();
545 int length = attributes.getLength();
546 for (int i = 0; i < length; i++) {
547 AttrImpl attr = (AttrImpl) attributes.item(i);
548 if (attr == null)
549 continue;
550 buffer.append(' ');
551 String attrName = generateAttrName(attr);
552 if (attrName != null)
553 buffer.append(attrName);
554 String attrValue = generateAttrValue(attr);
555 if (attrValue != null) {
556 // attr name only for HTML boolean and JSP
557 buffer.append('=');
558 buffer.append(attrValue);
559 }
560 }
561
562 String closeTag = generateCloseTag(element);
563 if (closeTag != null)
564 buffer.append(closeTag);
565
566 return buffer.toString();
567 }
568
569 /**
570 */
571 public String generateTagName(Element element) {
572 if (element == null)
573 return null;
david_williamsc39caaf2005-04-05 06:07:16 +0000574 IDOMElement xe = (IDOMElement) element;
david_williams96213482004-11-11 09:07:12 +0000575 String tagName = element.getTagName();
576 if (tagName == null)
577 return null;
578 if (xe.isJSPTag()) {
579 if (tagName.equals(JSPTag.JSP_EXPRESSION))
580 return JSPTag.EXPRESSION_TOKEN;
581 if (tagName.equals(JSPTag.JSP_DECLARATION))
582 return JSPTag.DECLARATION_TOKEN;
583 if (tagName.equals(JSPTag.JSP_DIRECTIVE))
584 return JSPTag.DIRECTIVE_TOKEN;
585 if (tagName.startsWith(JSPTag.JSP_DIRECTIVE)) {
586 int offset = JSPTag.JSP_DIRECTIVE.length() + 1; // after '.'
587 return (JSPTag.DIRECTIVE_TOKEN + tagName.substring(offset));
588 }
589 return (xe.isCommentTag()) ? tagName : null;
590 } else if (tagName.startsWith(JSPTag.TAG_OPEN)) {
591 if (!tagName.endsWith(JSPTag.TAG_CLOSE)) {
592 // close JSP
593 return (tagName + JSPTag.TAG_CLOSE);
594 }
595 } else if (xe.isCommentTag()) {
596 String prefix = element.getPrefix();
597 if (prefix.equals(SSI_PREFIX)) {
598 return (SSI_TOKEN + element.getLocalName());
599 }
600 } else {
601 if (!xe.isJSPTag() && xe.isGlobalTag() && // global tag
602 CMNodeUtil.getElementDeclaration(xe) != null) {
603 String newName = tagName;
604 switch (getTagNameCase(xe)) {
605 case DocumentTypeAdapter.UPPER_CASE :
606 newName = tagName.toUpperCase();
607 break;
608 case DocumentTypeAdapter.LOWER_CASE :
609 newName = tagName.toLowerCase();
610 break;
611 }
612 if (newName != tagName) {
613 tagName = newName;
614 setTagName(element, tagName);
615 }
616 }
617 }
618 return tagName;
619 }
620
621 /**
622 * generateText method
623 *
624 * @return java.lang.String
625 * @param text
626 * org.w3c.dom.Text
627 */
628 public String generateText(Text text) {
629 if (text == null)
630 return null;
631 TextImpl impl = (TextImpl) text;
632 String source = impl.getTextSource();
633 if (source != null)
634 return source;
635 return generateTextData(text, impl.getData());
636 }
637
638 /**
639 */
640 public String generateTextData(Text text, String data) {
641 if (data == null)
642 return null;
643 if (text == null)
644 return null;
645 TextImpl impl = (TextImpl) text;
646 if (impl.isJSPContent() || impl.isCDATAContent()) {
647 return new SourceValidator(impl).convertSource(data);
648 }
649 String source = data;
650
651 // convert special characters to character entities
652 StringBuffer buffer = null;
653 int offset = 0;
654 int length = data.length();
655 for (int i = 0; i < length; i++) {
656 String name = getCharName(data.charAt(i));
657 if (name == null)
658 continue;
659 if (buffer == null)
660 buffer = new StringBuffer(length + 8);
661 if (i > offset)
662 buffer.append(data.substring(offset, i));
663 buffer.append('&');
664 buffer.append(name);
665 buffer.append(';');
666 offset = i + 1;
667 }
668 if (buffer != null) {
669 if (length > offset)
670 buffer.append(data.substring(offset));
671 source = buffer.toString();
672 }
673
674 if (source == null || source.length() == 0)
675 return null;
676 return source;
677 }
678
679 /**
680 */
681 private int getAttrNameCase(Attr attr) {
682 DocumentImpl document = (DocumentImpl) attr.getOwnerDocument();
683 if (document == null)
684 return DocumentTypeAdapter.STRICT_CASE;
david_williamsfa0ae312005-06-20 20:16:53 +0000685 DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
david_williams96213482004-11-11 09:07:12 +0000686 if (adapter == null)
687 return DocumentTypeAdapter.STRICT_CASE;
688 return adapter.getAttrNameCase();
689 }
690
691 /**
692 */
693 private String getCharName(char c) {
694 switch (c) {
695 case '<' :
david_williamsc39caaf2005-04-05 06:07:16 +0000696 return IXMLCharEntity.LT_NAME;
david_williams96213482004-11-11 09:07:12 +0000697 case '>' :
david_williamsc39caaf2005-04-05 06:07:16 +0000698 return IXMLCharEntity.GT_NAME;
david_williams96213482004-11-11 09:07:12 +0000699 case '&' :
david_williamsc39caaf2005-04-05 06:07:16 +0000700 return IXMLCharEntity.AMP_NAME;
david_williams96213482004-11-11 09:07:12 +0000701 case '"' :
david_williamsc39caaf2005-04-05 06:07:16 +0000702 return IXMLCharEntity.QUOT_NAME;
david_williams96213482004-11-11 09:07:12 +0000703 }
704 return null;
705 }
706
707 /**
708 */
709 private int getTagNameCase(Element element) {
710 DocumentImpl document = (DocumentImpl) element.getOwnerDocument();
711 if (document == null)
712 return DocumentTypeAdapter.STRICT_CASE;
david_williamsfa0ae312005-06-20 20:16:53 +0000713 DocumentTypeAdapter adapter = (DocumentTypeAdapter) document.getAdapterFor(DocumentTypeAdapter.class);
david_williams96213482004-11-11 09:07:12 +0000714 if (adapter == null)
715 return DocumentTypeAdapter.STRICT_CASE;
716 return adapter.getTagNameCase();
717 }
718
719 /**
720 */
721 private boolean isBooleanAttr(Attr attr) {
722 if (attr == null)
723 return false;
724 CMAttributeDeclaration decl = CMNodeUtil.getAttributeDeclaration(attr);
725 if (decl == null)
726 return false;
727 CMDataType type = decl.getAttrType();
728 if (type == null)
729 return false;
730 String values[] = type.getEnumeratedValues();
731 if (values == null)
732 return false;
733 return (values.length == 1 && values[0].equals(decl.getAttrName()));
734 }
735}