Source Code Cross Referenced for FormatXMLize.java in  » Science » Cougaar12_4 » org » cougaar » lib » vishnu » client » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Cougaar12_4 » org.cougaar.lib.vishnu.client 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * <copyright>
003:         *  
004:         *  Copyright 1997-2004 BBNT Solutions, LLC
005:         *  under sponsorship of the Defense Advanced Research Projects
006:         *  Agency (DARPA).
007:         * 
008:         *  You can redistribute this software and/or modify it under the
009:         *  terms of the Cougaar Open Source License as published on the
010:         *  Cougaar Open Source Website (www.cougaar.org).
011:         * 
012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023:         *  
024:         * </copyright>
025:         */
026:
027:        package org.cougaar.lib.vishnu.client;
028:
029:        import java.util.Collection;
030:        import java.util.Date;
031:        import java.util.HashMap;
032:        import java.util.Iterator;
033:        import java.util.List;
034:        import java.util.Map;
035:        import java.util.HashSet;
036:        import java.util.Set;
037:
038:        import org.apache.xerces.dom.DocumentImpl;
039:
040:        import org.cougaar.core.util.UID;
041:        import org.cougaar.core.util.UniqueObject;
042:        import org.cougaar.core.util.PropertyNameValue;
043:
044:        import org.cougaar.util.log.Logger;
045:
046:        import org.w3c.dom.Document;
047:        import org.w3c.dom.Element;
048:        import org.w3c.dom.NodeList;
049:
050:        /**
051:         * Create XML document in the Vishnu ObjectFormat format, 
052:         * directly from ALP objects.
053:         * <p>
054:         * Create and return xml for first class log plan objects.
055:         * <p>
056:         * Element name is extracted from object class, by taking the
057:         * last field of the object class, and dropping a trailing "Impl",
058:         * if it exists.
059:         */
060:
061:        public class FormatXMLize extends BaseXMLize implements  XMLizer {
062:            protected Class collectionClass;
063:            protected Class enumerationClass;
064:            protected Class dateClass;
065:            protected Class latitudeClass;
066:            protected Class longitudeClass;
067:            protected Class UIDClass;
068:            protected String numberString = "number";
069:            protected String booleanString = "boolean";
070:            protected String dateString = "datetime";
071:            protected String latitudeString = "latlong";
072:
073:            // controls how deep down the object hierarchy to go
074:            protected final int RECURSION_DEPTH = 9;
075:
076:            public FormatXMLize(Logger logger) {
077:                super (logger);
078:                try {
079:                    collectionClass = Class.forName("java.util.Collection");
080:                    dateClass = Class.forName("java.util.Date");
081:                    latitudeClass = Class
082:                            .forName("org.cougaar.planning.ldm.measure.Latitude");
083:                    longitudeClass = Class
084:                            .forName("org.cougaar.planning.ldm.measure.Longitude");
085:                    UIDClass = Class.forName("org.cougaar.core.util.UID");
086:                    enumerationClass = Class.forName("java.util.Enumeration");
087:                } catch (ClassNotFoundException cnfe) {
088:                }
089:            }
090:
091:            /** 
092:             * <b>Recursively</b> introspect and add nodes to the XML document.
093:             * <p>
094:             * Keeps a Set of objects (as these can be circular) and stops 
095:             * when it tries to introspect over an object a second time.
096:             * <p>
097:             * Also keeps a depth counter, decrements for each call to addNodes, 
098:             * and stops when the counter is zero.  Use Integer.MAX_VALUE to 
099:             * indicate an unlimited search.
100:             */
101:
102:            Map unique = new HashMap();
103:            Set globals = new HashSet();
104:
105:            public Map getUnique() {
106:                return unique;
107:            }
108:
109:            protected void addNodes(Document doc, Object obj,
110:                    Element parentElement, int searchDepth,
111:                    Collection createdNodes) {
112:                if (obj == null) {
113:                    return;
114:                }
115:
116:                if (logger.isDebugEnabled()) {
117:                    if (obj instanceof  org.cougaar.planning.ldm.asset.PropertyGroup) {
118:                        if (unique.containsKey(obj))
119:                            unique.put(obj, new Integer(((Integer) unique
120:                                    .get(obj)).intValue() + 1));
121:                        else
122:                            unique.put(obj, new Integer(1));
123:                    }
124:                }
125:
126:                if (logger.isDebugEnabled())
127:                    logger.debug("addNodes - class " + obj.getClass());
128:
129:                if (ignoreClass(obj.getClass())) {
130:                    if (logger.isDebugEnabled())
131:                        logger.debug("----> ignored!");
132:                    return;
133:                }
134:
135:                //	debug ("Search depth " + searchDepth);
136:                if (searchDepth <= 0) {
137:                    generateElementReachedMaxDepth(doc, parentElement, obj);
138:                    return;
139:                }
140:
141:                Map listProps = new HashMap();
142:                List propertyNameValues = getProperties(obj, listProps);
143:
144:                boolean foundDateAspect = false;
145:
146:                // add the nodes for the properties and values
147:                for (int i = 0; i < propertyNameValues.size();) {
148:                    PropertyNameValue pnv = (PropertyNameValue) propertyNameValues
149:                            .get(i);
150:                    foundDateAspect = checkForDateAspect(pnv, foundDateAspect);
151:
152:                    boolean isFirst = false;
153:                    Integer numListElems = (Integer) listProps.get(pnv.name);
154:                    boolean isList = (numListElems != null);
155:
156:                    if (isList) {
157:                        isFirst = true;
158:                        for (int j = 0; j < numListElems.intValue(); j++) {
159:                            pnv = (PropertyNameValue) propertyNameValues
160:                                    .get(i++);
161:                            generateElem(doc, parentElement, pnv.name,
162:                                    pnv.value, searchDepth, isList, isFirst,
163:                                    createdNodes);
164:                            isFirst = false;
165:                        }
166:                    } else {
167:                        generateElem(doc, parentElement, pnv.name, pnv.value,
168:                                searchDepth, isList, isFirst, createdNodes);
169:                        i++;
170:                    }
171:                }
172:            }
173:
174:            protected boolean checkForDateAspect(PropertyNameValue pnv,
175:                    boolean foundDateAspect) {
176:                if (foundDateAspect && pnv.name.charAt(0) == 'v') {
177:                    if (pnv.name.equals("value")) {
178:                        double millis = Double.parseDouble((String) pnv.value);
179:                        pnv.value = new Date((long) millis);
180:                    }
181:                } else if (pnv.name.charAt(0) == 'a') {
182:                    if (pnv.name.equals("aspectType")) {
183:                        String value = (String) pnv.value;
184:                        char first = value.charAt(0);
185:                        if ((first == '0')
186:                                || ((first == '1') && (value.length() == 1))
187:                                || ((first == '1') && (value.charAt(1) == '.' || value
188:                                        .charAt(1) == '3')))
189:                            foundDateAspect = true;
190:                    }
191:                }
192:                return foundDateAspect;
193:            }
194:
195:            /** subclass to generate different tag */
196:            protected Element createRootNode(Document doc, String tag,
197:                    boolean isTask, boolean isResource, Object obj,
198:                    String resourceClassName) {
199:                return createObjectFormat(doc, tag, isTask, isResource, obj,
200:                        resourceClassName);
201:            }
202:
203:            /**
204:             * Already seen this object or reached maximum depth. 
205:             * Write the UID if possible, otherwise write the "toString".
206:             */
207:            protected void generateElementReachedMaxDepth(Document doc,
208:                    Element parentElement, Object obj) {
209:                if (logger.isDebugEnabled())
210:                    logger.debug("Object traversed already/max depth: "
211:                            + obj.getClass().toString() + " " + obj);
212:                if (isUniqueObject(obj)) {
213:                    Element item = createFieldFormat(doc, "UID", "string",
214:                            false, false);
215:                    if (logger.isDebugEnabled())
216:                        logger.debug("maxDepth - " + "UID" + " - " + "string");
217:
218:                    parentElement.appendChild(item);
219:                } else {
220:                    parentElement.appendChild(createFieldFormat(doc,
221:                            getTypeFor(obj), obj, false, false));
222:                    if (logger.isDebugEnabled())
223:                        logger.debug("maxDepth - " + obj);
224:                }
225:            }
226:
227:            protected void generateLeaf(Document doc, Element parentElement,
228:                    String propertyName, Object propertyValue) {
229:                Element item = createFieldFormat(doc, propertyName,
230:                        propertyValue, false, false);
231:
232:                parentElement.appendChild(item);
233:
234:                // only set keys on tasks and resources
235:                correctKey(parentElement, item);
236:
237:                if (logger.isDebugEnabled())
238:                    logger.debug("isLeaf - " + propertyName + " - "
239:                            + propertyValue);
240:            }
241:
242:            protected void generateNonLeaf(Document doc, Element parentElement,
243:                    String propertyName, Object propertyValue, int searchDepth,
244:                    boolean isList, boolean isFirst, Collection createdNodes) {
245:                // this removes the class name following the $ for Locked classes
246:                int index = propertyName.indexOf('$');
247:                if (index > 0) {
248:                    propertyName = propertyName.substring(0, index);
249:                }
250:                boolean skip = skipObject(propertyValue);
251:
252:                Element fieldNode = null;
253:
254:                if (logger.isDebugEnabled()
255:                        && !((isList && isFirst) || !isList))
256:                    logger.debug("skipping field format for - " + propertyName
257:                            + " - " + propertyValue);
258:
259:                if (!ignoreObject(propertyValue)
260:                        && ((isList && isFirst) || !isList)) {
261:                    fieldNode = createFieldFormat(doc, propertyName,
262:                            propertyValue, isList, !skip);
263:                    parentElement.appendChild(fieldNode);
264:                    // only set keys on tasks and resources
265:                    correctKey(parentElement, fieldNode);
266:                    if (logger.isDebugEnabled())
267:                        logger.debug("nonLeaf - " + propertyName + " - "
268:                                + propertyValue);
269:                }
270:
271:                if (!skip) {
272:                    if (propertyValue instanceof  org.cougaar.planning.ldm.asset.PropertyGroup) {
273:                        if (globals.contains(propertyValue)) {
274:                            return;
275:                        }
276:                    }
277:
278:                    Element item = createObjectFormat(doc, propertyName, false,
279:                            false, propertyValue, null);
280:                    createdNodes.add(item);
281:                    // recurse!
282:
283:                    addNodes(doc, propertyValue, item, (searchDepth - 1),
284:                            createdNodes);
285:                    if (item.getChildNodes().getLength() == 0) {
286:                        //		createdNodes.remove (item);
287:                        //		parentElement.removeChild (fieldNode);
288:                        if (logger.isDebugEnabled())
289:                            logger.debug("nonLeaf - REMOVING? - "
290:                                    + propertyName + " - " + propertyValue);
291:
292:                    }
293:                    if ((propertyName.charAt(0) == 'r')
294:                            && propertyName.equals("roleSchedule")) {
295:                        removeChildNamed(item, "scheduleElements");
296:                        removeChildNamed(item, "availableSchedule");
297:
298:                        addIntervalNamed("scheduleElements", doc, item);
299:                        addIntervalNamed("availableSchedule", doc, item);
300:                    }
301:
302:                    globals.add(propertyValue);
303:                }
304:            }
305:
306:            protected void removeChildNamed(Element roleScheduleImpl,
307:                    String childName) {
308:                NodeList children = roleScheduleImpl.getChildNodes();
309:                for (int i = 0; i < children.getLength(); i++) {
310:                    Element child = (Element) children.item(i);
311:                    if (child.getAttribute("name").equals(childName)) {
312:                        if (logger.isDebugEnabled())
313:                            logger.debug("found " + childName + ", removing.");
314:
315:                        roleScheduleImpl.removeChild(child);
316:                        break;
317:                    }
318:                }
319:            }
320:
321:            /** all property groups become globals, except for item id pg */
322:            protected boolean isGlobal(Object obj) {
323:                boolean isPropertyGroup = (obj instanceof  org.cougaar.planning.ldm.asset.PropertyGroup);
324:                boolean isItemIDPropertyGroup = (obj instanceof  org.cougaar.planning.ldm.asset.ItemIdentificationPG);
325:                //	boolean isPrepPhrase = (obj instanceof org.cougaar.planning.ldm.plan.PrepositionalPhrase);
326:                boolean isGlobal = isPropertyGroup && !isItemIDPropertyGroup; // || isPrepPhrase;
327:                return isGlobal;
328:            }
329:
330:            protected void correctKey(Element parentElement, Element item) {
331:                // only set keys on tasks and resources
332:                if ((parentElement.getAttribute("is_task").charAt(0) == 'f')
333:                        && (parentElement.getAttribute("is_resource").charAt(0) == 'f')
334:                        && (item.getAttribute("is_key").charAt(0) == 't')) {
335:                    if (logger.isDebugEnabled())
336:                        logger.debug("correctKey - CORRECTING key");
337:                    item.setAttribute("is_key", "false");
338:                }
339:
340:                if (logger.isDebugEnabled()) {
341:                    boolean allFalse = parentElement.getAttribute("is_task")
342:                            .charAt(0) == 'f'
343:                            & parentElement.getAttribute("is_resource").charAt(
344:                                    0) == 'f'
345:                            & item.getAttribute("is_key").charAt(0) == 'f';
346:                    if (!allFalse)
347:                        logger.debug("generateLeaf - parent task "
348:                                + parentElement.getAttribute("is_task").charAt(
349:                                        0)
350:                                + " resource "
351:                                + parentElement.getAttribute("is_resource")
352:                                        .charAt(0) + " item key "
353:                                + item.getAttribute("is_key").charAt(0));
354:                }
355:            }
356:
357:            /** 
358:             * need to have special code to add plan element intervals to role schedule format, since
359:             * bean properties don't include them
360:             */
361:            protected void addScheduleElements(Document doc, Element item) {
362:                addIntervalNamed("scheduleElements", doc, item);
363:            }
364:
365:            protected void addIntervalNamed(String name, Document doc,
366:                    Element item) {
367:                Element elem = doc.createElement("FIELDFORMAT");
368:                elem.setAttribute("name", name);
369:                elem.setAttribute("is_subobject", "true");
370:                elem.setAttribute("is_list", "true");
371:                elem.setAttribute("is_key", "false");
372:                elem.setAttribute("datatype", "interval");
373:                item.appendChild(elem);
374:            }
375:
376:            /** 
377:             * implemented for XMLizer interface <p>
378:             *
379:             * creates an DOM Document out of the collection of items passed in, <br>
380:             * with the name of the resource class.
381:             **/
382:            public Document createDoc(Collection items,
383:                    Collection ignoredChangedItems, String assetClassName) {
384:                Document doc = new DocumentImpl();
385:                Element root = doc.createElement("PROBLEM");
386:                doc.appendChild(root);
387:                Element df = doc.createElement("DATAFORMAT");
388:                root.appendChild(df);
389:
390:                Element element = null;
391:                for (Iterator iter = items.iterator(); iter.hasNext();) {
392:                    Collection nodes = getPlanObjectXMLNodes(iter.next(), doc,
393:                            RECURSION_DEPTH, assetClassName);
394:                    for (Iterator iter2 = nodes.iterator(); iter2.hasNext();)
395:                        df.appendChild((Element) iter2.next());
396:                }
397:
398:                if (logger.isDebugEnabled()) {
399:                    int i = 0;
400:                    for (Iterator iter = unique.keySet().iterator(); iter
401:                            .hasNext();) {
402:                        Object thing = iter.next();
403:                        logger.debug("" + i++ + " - " + thing.getClass()
404:                                + " - " + unique.get(thing));
405:                    }
406:                }
407:                return doc;
408:            }
409:
410:            protected Element createObjectFormat(Document doc, String name,
411:                    boolean isTask, boolean isResource, Object theObj,
412:                    String resourceClassName) {
413:                Element elem = doc.createElement("OBJECTFORMAT");
414:                elem.setAttribute("is_task", (isTask) ? "true" : "false");
415:                elem.setAttribute("is_resource", (isResource) ? "true"
416:                        : "false");
417:                String cn;
418:
419:                if (isResource)
420:                    cn = resourceClassName;
421:                else {
422:                    cn = "" + theObj.getClass();
423:                    cn = cn.substring(cn.lastIndexOf('.') + 1);
424:                    cn = cn.substring(cn.lastIndexOf('$') + 1);
425:                }
426:
427:                elem.setAttribute("name", (isTask) ? name : cn);
428:
429:                return elem;
430:            }
431:
432:            protected Element createFieldFormat(Document doc, String name,
433:                    Object theObj, boolean isList, boolean isSubobject) {
434:                Element elem = doc.createElement("FIELDFORMAT");
435:                elem.setAttribute("name", name);
436:                boolean isKey = isKey(theObj);
437:
438:                elem.setAttribute("is_subobject",
439:                        ((isSubobject && !isKey) || (latitudeClass
440:                                .isInstance(theObj))) ? "true" : "false");
441:                String cn = "" + theObj.getClass();
442:                if (isSubobject) {
443:                    cn = cn.substring(cn.lastIndexOf('.') + 1);
444:                    cn = cn.substring(cn.lastIndexOf('$') + 1);
445:                    elem.setAttribute("datatype", cn);
446:                } else
447:                    elem.setAttribute("datatype", getTypeFor(theObj));
448:                elem.setAttribute("is_list", (isList) ? "true" : "false");
449:                elem.setAttribute("is_key", (isKey(theObj)) ? "true" : "false");
450:
451:                // if it's a global set it's attr
452:                if (isGlobal(theObj)) {
453:                    elem.setAttribute("is_globalptr", "true");
454:                    elem.setAttribute("is_subobject", "false");
455:                }
456:
457:                if (logger.isDebugEnabled() && isList(theObj) && !isList)
458:                    logger.debug("WARNING - disaggrement over " + name + " - "
459:                            + name.getClass());
460:
461:                return elem;
462:            }
463:
464:            protected boolean isList(Object theObj) {
465:                return collectionClass.isInstance(theObj)
466:                        || theObj.getClass().isArray()
467:                        || enumerationClass.isInstance(theObj);
468:            }
469:
470:            protected String getTypeFor(Object theObj) {
471:                if (numberClass.isInstance(theObj))
472:                    return numberString;
473:                if (dateClass.isInstance(theObj))
474:                    return dateString;
475:                if (latitudeClass.isInstance(theObj))
476:                    return latitudeString;
477:                if (booleanClass.isInstance(theObj))
478:                    return booleanString;
479:
480:                String objAsString = theObj.toString();
481:
482:                if (objAsString.length() == 0)
483:                    return "string";
484:
485:                char firstChar = objAsString.charAt(0);
486:
487:                if (((firstChar == 't') || (firstChar == 'f'))
488:                        && (objAsString.equals("true") || objAsString
489:                                .equals("false"))) {
490:                    //	  if (logger.isDebugEnabled())
491:                    //		logger.debug ("got here - " + objAsString + " but not boolean - " + theObj.getClass ());
492:                    return booleanString;
493:                }
494:
495:                if (Character.isDigit(firstChar)) {
496:                    boolean isNumber = false;
497:                    try {
498:                        Integer.parseInt(objAsString);
499:                        isNumber = true;
500:                    } catch (NumberFormatException nfe) {
501:                    }
502:
503:                    try {
504:                        Double.parseDouble(objAsString);
505:                        isNumber = true;
506:                    } catch (NumberFormatException nfe) {
507:                    }
508:                    if (isNumber) {
509:                        //		if (logger.isDebugEnabled())
510:                        //		  logger.debug ("got here - " + objAsString + " but not number - " + theObj.getClass ());
511:                        return numberString;
512:                    }
513:                }
514:
515:                if (firstChar == 'I' || firstChar == '-') {
516:                    if (objAsString.equals("Infinity"))
517:                        return numberString;
518:                    else if (objAsString.equals("-Infinity"))
519:                        return numberString;
520:                }
521:
522:                return "string";
523:            }
524:
525:            protected boolean skipObject(Object theObj) {
526:                return (dateClass.isInstance(theObj)
527:                        || latitudeClass.isInstance(theObj)
528:                        || longitudeClass.isInstance(theObj) || UIDClass
529:                        .isInstance(theObj));
530:            }
531:
532:            protected boolean ignoreObject(Object theObj) {
533:                return longitudeClass.isInstance(theObj);
534:            }
535:
536:            protected boolean isKey(Object theObj) {
537:                return UIDClass.isInstance(theObj);
538:            }
539:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.