Source Code Cross Referenced for DroolsBuilder.java in  » Rule-Engine » drolls-Rule-Engine » org » drools » eclipse » builder » 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 » Rule Engine » drolls Rule Engine » org.drools.eclipse.builder 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.drools.eclipse.builder;
002:
003:        import java.io.IOException;
004:        import java.io.InputStream;
005:        import java.io.InputStreamReader;
006:        import java.io.Reader;
007:        import java.util.ArrayList;
008:        import java.util.Iterator;
009:        import java.util.List;
010:        import java.util.Map;
011:
012:        import org.antlr.runtime.RecognitionException;
013:        import org.drools.brms.client.modeldriven.brl.RuleModel;
014:        import org.drools.brms.server.util.BRDRLPersistence;
015:        import org.drools.brms.server.util.BRXMLPersistence;
016:        import org.drools.commons.jci.problems.CompilationProblem;
017:        import org.drools.compiler.DroolsError;
018:        import org.drools.compiler.DroolsParserException;
019:        import org.drools.compiler.FactTemplateError;
020:        import org.drools.compiler.FieldTemplateError;
021:        import org.drools.compiler.FunctionError;
022:        import org.drools.compiler.GlobalError;
023:        import org.drools.compiler.ImportError;
024:        import org.drools.compiler.PackageBuilder;
025:        import org.drools.compiler.ParserError;
026:        import org.drools.compiler.ProcessBuilder;
027:        import org.drools.compiler.RuleError;
028:        import org.drools.decisiontable.InputType;
029:        import org.drools.decisiontable.SpreadsheetCompiler;
030:        import org.drools.eclipse.DRLInfo;
031:        import org.drools.eclipse.DroolsEclipsePlugin;
032:        import org.drools.eclipse.flow.ruleflow.core.RuleFlowProcessWrapper;
033:        import org.drools.eclipse.preferences.IDroolsConstants;
034:        import org.drools.lang.ExpanderException;
035:        import org.eclipse.core.resources.IFile;
036:        import org.eclipse.core.resources.IMarker;
037:        import org.eclipse.core.resources.IProject;
038:        import org.eclipse.core.resources.IResource;
039:        import org.eclipse.core.resources.IResourceDelta;
040:        import org.eclipse.core.resources.IResourceDeltaVisitor;
041:        import org.eclipse.core.resources.IResourceVisitor;
042:        import org.eclipse.core.resources.IWorkspace;
043:        import org.eclipse.core.resources.IWorkspaceRunnable;
044:        import org.eclipse.core.resources.IncrementalProjectBuilder;
045:        import org.eclipse.core.runtime.CoreException;
046:        import org.eclipse.core.runtime.IProgressMonitor;
047:        import org.eclipse.core.runtime.OperationCanceledException;
048:        import org.eclipse.jdt.core.IClasspathEntry;
049:        import org.eclipse.jdt.core.IJavaProject;
050:        import org.eclipse.jdt.core.JavaCore;
051:        import org.eclipse.jdt.core.JavaModelException;
052:
053:        import com.thoughtworks.xstream.XStream;
054:
055:        /**
056:         * Automatically syntax checks .drl files and adds possible
057:         * errors or warnings to the problem list. Nominally is triggerd on save.
058:         * 
059:         * @author <a href="mailto:kris_verlaenen@hotmail.com">kris verlaenen </a>
060:         */
061:        public class DroolsBuilder extends IncrementalProjectBuilder {
062:
063:            public static final String BUILDER_ID = "org.drools.eclipse.droolsbuilder";
064:
065:            protected IProject[] build(int kind, Map args,
066:                    IProgressMonitor monitor) throws CoreException {
067:                IProject currentProject = getProject();
068:                if (currentProject == null || !currentProject.isAccessible()) {
069:                    return new IProject[0];
070:                }
071:                try {
072:                    if (monitor != null && monitor.isCanceled())
073:                        throw new OperationCanceledException();
074:
075:                    if (kind == IncrementalProjectBuilder.FULL_BUILD) {
076:                        fullBuild(monitor);
077:                    } else {
078:                        IResourceDelta delta = getDelta(getProject());
079:                        if (delta == null) {
080:                            fullBuild(monitor);
081:                        } else {
082:                            incrementalBuild(delta, monitor);
083:                        }
084:                    }
085:                } catch (CoreException e) {
086:                    IMarker marker = currentProject
087:                            .createMarker(IDroolsModelMarker.DROOLS_MODEL_PROBLEM_MARKER);
088:                    marker.setAttribute(IMarker.MESSAGE,
089:                            "Error when trying to build Drools project: "
090:                                    + e.getLocalizedMessage());
091:                    marker.setAttribute(IMarker.SEVERITY,
092:                            IMarker.SEVERITY_ERROR);
093:                }
094:                return getRequiredProjects(currentProject);
095:            }
096:
097:            protected void fullBuild(IProgressMonitor monitor)
098:                    throws CoreException {
099:                getProject().accept(new DroolsBuildVisitor());
100:            }
101:
102:            protected void incrementalBuild(IResourceDelta delta,
103:                    IProgressMonitor monitor) throws CoreException {
104:                boolean buildAll = DroolsEclipsePlugin.getDefault()
105:                        .getPreferenceStore().getBoolean(
106:                                IDroolsConstants.BUILD_ALL);
107:                if (buildAll) {
108:                    // to make sure that all rules are checked when a java file is changed 
109:                    fullBuild(monitor);
110:                } else {
111:                    delta.accept(new DroolsBuildDeltaVisitor());
112:                }
113:            }
114:
115:            private class DroolsBuildVisitor implements  IResourceVisitor {
116:                public boolean visit(IResource res) {
117:                    return parseResource(res, true);
118:                }
119:            }
120:
121:            private class DroolsBuildDeltaVisitor implements 
122:                    IResourceDeltaVisitor {
123:                public boolean visit(IResourceDelta delta) throws CoreException {
124:                    return parseResource(delta.getResource(), false);
125:                }
126:            }
127:
128:            private boolean parseResource(IResource res, boolean clean) {
129:                try {
130:                    IJavaProject project = JavaCore.create(res.getProject());
131:                    // exclude files that are located in the output directory,
132:                    // unless the ouput directory is the same as the project location
133:                    if (!project.getOutputLocation().equals(project.getPath())
134:                            && project.getOutputLocation().isPrefixOf(
135:                                    res.getFullPath())) {
136:                        return false;
137:                    }
138:                } catch (JavaModelException e) {
139:                    // do nothing
140:                }
141:
142:                if (res instanceof  IFile
143:                        && ("drl".equals(res.getFileExtension())
144:                                || "dslr".equals(res.getFileExtension()) || ".package"
145:                                .equals(res.getName()))) {
146:                    removeProblemsFor(res);
147:                    try {
148:                        if (clean) {
149:                            DroolsEclipsePlugin.getDefault()
150:                                    .invalidateResource(res);
151:                        }
152:                        DroolsBuildMarker[] markers = parseDRLFile(
153:                                (IFile) res,
154:                                new String(
155:                                        Util
156:                                                .getResourceContentsAsCharArray((IFile) res)));
157:                        for (int i = 0; i < markers.length; i++) {
158:                            createMarker(res, markers[i].getText(), markers[i]
159:                                    .getLine());
160:                        }
161:                    } catch (Throwable t) {
162:                        createMarker(res, t.getMessage(), -1);
163:                    }
164:                    return false;
165:                } else if (res instanceof  IFile
166:                        && "xls".equals(res.getFileExtension())) {
167:                    removeProblemsFor(res);
168:                    try {
169:                        if (clean) {
170:                            DroolsEclipsePlugin.getDefault()
171:                                    .invalidateResource(res);
172:                        }
173:                        DroolsBuildMarker[] markers = parseXLSFile((IFile) res);
174:                        for (int i = 0; i < markers.length; i++) {
175:                            createMarker(res, markers[i].getText(), markers[i]
176:                                    .getLine());
177:                        }
178:                    } catch (Throwable t) {
179:                        createMarker(res, t.getMessage(), -1);
180:                    }
181:                    return false;
182:                } else if (res instanceof  IFile
183:                        && "brl".equals(res.getFileExtension())) {
184:                    removeProblemsFor(res);
185:                    try {
186:                        if (clean) {
187:                            DroolsEclipsePlugin.getDefault()
188:                                    .invalidateResource(res);
189:                        }
190:                        DroolsBuildMarker[] markers = parseBRLFile((IFile) res);
191:                        for (int i = 0; i < markers.length; i++) {
192:                            createMarker(res, markers[i].getText(), markers[i]
193:                                    .getLine());
194:                        }
195:                    } catch (Throwable t) {
196:                        createMarker(res, t.getMessage(), -1);
197:                    }
198:                    return false;
199:                } else if (res instanceof  IFile
200:                        && "rf".equals(res.getFileExtension())) {
201:                    removeProblemsFor(res);
202:                    try {
203:                        if (clean) {
204:                            DroolsEclipsePlugin.getDefault()
205:                                    .invalidateResource(res);
206:                        }
207:                        DroolsBuildMarker[] markers = parseRuleFlowFile((IFile) res);
208:                        for (int i = 0; i < markers.length; i++) {
209:                            createMarker(res, markers[i].getText(), markers[i]
210:                                    .getLine());
211:                        }
212:                    } catch (Throwable t) {
213:                        createMarker(res, t.getMessage(), -1);
214:                    }
215:                    return false;
216:                }
217:
218:                return true;
219:            }
220:
221:            private DroolsBuildMarker[] parseDRLFile(IFile file, String content) {
222:                List markers = new ArrayList();
223:                try {
224:                    DRLInfo drlInfo = DroolsEclipsePlugin.getDefault()
225:                            .parseResource(file, true);
226:                    //parser errors
227:                    markParseErrors(markers, drlInfo.getParserErrors());
228:                    markOtherErrors(markers, drlInfo.getBuilderErrors());
229:                } catch (DroolsParserException e) {
230:                    // we have an error thrown from DrlParser
231:                    Throwable cause = e.getCause();
232:                    if (cause instanceof  RecognitionException) {
233:                        RecognitionException recogErr = (RecognitionException) cause;
234:                        markers.add(new DroolsBuildMarker(
235:                                recogErr.getMessage(), recogErr.line)); //flick back the line number
236:                    }
237:                } catch (Exception t) {
238:                    String message = t.getMessage();
239:                    if (message == null || message.trim().equals("")) {
240:                        message = "Error: " + t.getClass().getName();
241:                    }
242:                    markers.add(new DroolsBuildMarker(message));
243:                }
244:                return (DroolsBuildMarker[]) markers
245:                        .toArray(new DroolsBuildMarker[markers.size()]);
246:            }
247:
248:            private DroolsBuildMarker[] parseXLSFile(IFile file) {
249:                List markers = new ArrayList();
250:                try {
251:                    SpreadsheetCompiler converter = new SpreadsheetCompiler();
252:                    String drl = converter.compile(file.getContents(),
253:                            InputType.XLS);
254:                    DRLInfo drlInfo = DroolsEclipsePlugin.getDefault()
255:                            .parseXLSResource(drl, file);
256:                    // parser errors
257:                    markParseErrors(markers, drlInfo.getParserErrors());
258:                    markOtherErrors(markers, drlInfo.getBuilderErrors());
259:                } catch (DroolsParserException e) {
260:                    // we have an error thrown from DrlParser
261:                    Throwable cause = e.getCause();
262:                    if (cause instanceof  RecognitionException) {
263:                        RecognitionException recogErr = (RecognitionException) cause;
264:                        markers.add(new DroolsBuildMarker(
265:                                recogErr.getMessage(), recogErr.line)); //flick back the line number
266:                    }
267:                } catch (Exception t) {
268:                    String message = t.getMessage();
269:                    if (message == null || message.trim().equals("")) {
270:                        message = "Error: " + t.getClass().getName();
271:                    }
272:                    markers.add(new DroolsBuildMarker(message));
273:                }
274:                return (DroolsBuildMarker[]) markers
275:                        .toArray(new DroolsBuildMarker[markers.size()]);
276:            }
277:
278:            private DroolsBuildMarker[] parseBRLFile(IFile file) {
279:                List markers = new ArrayList();
280:                try {
281:                    String brl = convertToString(file.getContents());
282:                    RuleModel model = BRXMLPersistence.getInstance().unmarshal(
283:                            brl);
284:                    String drl = BRDRLPersistence.getInstance().marshal(model);
285:
286:                    // TODO pass this through DSL converter in case brl is based on dsl
287:
288:                    DRLInfo drlInfo = DroolsEclipsePlugin.getDefault()
289:                            .parseBRLResource(drl, file);
290:                    // parser errors
291:                    markParseErrors(markers, drlInfo.getParserErrors());
292:                    markOtherErrors(markers, drlInfo.getBuilderErrors());
293:                } catch (DroolsParserException e) {
294:                    // we have an error thrown from DrlParser
295:                    Throwable cause = e.getCause();
296:                    if (cause instanceof  RecognitionException) {
297:                        RecognitionException recogErr = (RecognitionException) cause;
298:                        markers.add(new DroolsBuildMarker(
299:                                recogErr.getMessage(), recogErr.line)); //flick back the line number
300:                    }
301:                } catch (Exception t) {
302:                    String message = t.getMessage();
303:                    if (message == null || message.trim().equals("")) {
304:                        message = "Error: " + t.getClass().getName();
305:                    }
306:                    markers.add(new DroolsBuildMarker(message));
307:                }
308:                return (DroolsBuildMarker[]) markers
309:                        .toArray(new DroolsBuildMarker[markers.size()]);
310:            }
311:
312:            private DroolsBuildMarker[] parseRuleFlowFile(IFile file) {
313:                List markers = new ArrayList();
314:                try {
315:                    String ruleflow = convertToString(file.getContents());
316:                    XStream stream = new XStream();
317:                    stream.setMode(XStream.ID_REFERENCES);
318:
319:                    ClassLoader oldLoader = Thread.currentThread()
320:                            .getContextClassLoader();
321:                    ClassLoader newLoader = this .getClass().getClassLoader();
322:                    try {
323:                        Thread.currentThread().setContextClassLoader(newLoader);
324:                        Object o = stream.fromXML(ruleflow);
325:                        if (o instanceof  RuleFlowProcessWrapper) {
326:                            ProcessBuilder processBuilder = new ProcessBuilder(
327:                                    new PackageBuilder());
328:                            processBuilder
329:                                    .addProcess(((RuleFlowProcessWrapper) o)
330:                                            .getRuleFlowProcess());
331:                            markParseErrors(markers, processBuilder.getErrors());
332:                        }
333:                    } finally {
334:                        Thread.currentThread().setContextClassLoader(oldLoader);
335:                    }
336:                } catch (Exception t) {
337:                    String message = t.getMessage();
338:                    if (message == null || message.trim().equals("")) {
339:                        message = "Error: " + t.getClass().getName();
340:                    }
341:                    markers.add(new DroolsBuildMarker(message));
342:                }
343:                return (DroolsBuildMarker[]) markers
344:                        .toArray(new DroolsBuildMarker[markers.size()]);
345:            }
346:
347:            private static String convertToString(final InputStream inputStream)
348:                    throws IOException {
349:                Reader reader = new InputStreamReader(inputStream);
350:                final StringBuffer text = new StringBuffer();
351:                final char[] buf = new char[1024];
352:                int len = 0;
353:                while ((len = reader.read(buf)) >= 0) {
354:                    text.append(buf, 0, len);
355:                }
356:                return text.toString();
357:            }
358:
359:            /**
360:             * This will create markers for parse errors.
361:             * Parse errors mean that antlr has picked up some major typos in the input source.
362:             */
363:            private void markParseErrors(List markers, List parserErrors) {
364:                for (Iterator iter = parserErrors.iterator(); iter.hasNext();) {
365:                    Object error = iter.next();
366:                    if (error instanceof  ParserError) {
367:                        ParserError err = (ParserError) error;
368:                        markers.add(new DroolsBuildMarker(err.getMessage(), err
369:                                .getRow()));
370:                    } else if (error instanceof  ExpanderException) {
371:                        ExpanderException exc = (ExpanderException) error;
372:                        // TODO line mapping is incorrect
373:                        markers
374:                                .add(new DroolsBuildMarker(exc.getMessage(), -1));
375:                    } else {
376:                        markers.add(new DroolsBuildMarker(error.toString()));
377:                    }
378:                }
379:            }
380:
381:            /**
382:             * This will create markers for build errors that happen AFTER parsing.
383:             */
384:            private void markOtherErrors(List markers, DroolsError[] buildErrors) {
385:                // TODO are there warnings too?
386:                for (int i = 0; i < buildErrors.length; i++) {
387:                    DroolsError error = buildErrors[i];
388:                    if (error instanceof  GlobalError) {
389:                        GlobalError globalError = (GlobalError) error;
390:                        markers.add(new DroolsBuildMarker(globalError
391:                                .getGlobal(), -1));
392:                    } else if (error instanceof  RuleError) {
393:                        RuleError ruleError = (RuleError) error;
394:                        // TODO try to retrieve line number (or even character start-end)
395:                        // disabled for now because line number are those of the rule class,
396:                        // not the rule file itself
397:                        if (ruleError.getObject() instanceof  CompilationProblem[]) {
398:                            CompilationProblem[] problems = (CompilationProblem[]) ruleError
399:                                    .getObject();
400:                            for (int j = 0; j < problems.length; j++) {
401:                                markers.add(new DroolsBuildMarker(problems[j]
402:                                        .getMessage(), ruleError.getLine()));
403:                            }
404:                        } else {
405:                            markers.add(new DroolsBuildMarker(ruleError
406:                                    .getRule().getName()
407:                                    + ":" + ruleError.getMessage(), ruleError
408:                                    .getLine()));
409:                        }
410:                    } else if (error instanceof  ParserError) {
411:                        ParserError parserError = (ParserError) error;
412:                        // TODO try to retrieve character start-end
413:                        markers.add(new DroolsBuildMarker(parserError
414:                                .getMessage(), parserError.getRow()));
415:                    } else if (error instanceof  FunctionError) {
416:                        FunctionError functionError = (FunctionError) error;
417:                        // TODO add line to function error
418:                        // TODO try to retrieve character start-end
419:                        if (functionError.getObject() instanceof  CompilationProblem[]) {
420:                            CompilationProblem[] problems = (CompilationProblem[]) functionError
421:                                    .getObject();
422:                            for (int j = 0; j < problems.length; j++) {
423:                                markers.add(new DroolsBuildMarker(problems[j]
424:                                        .getMessage(), functionError
425:                                        .getErrorLines()[j]));
426:                            }
427:                        } else {
428:                            markers.add(new DroolsBuildMarker(functionError
429:                                    .getFunctionDescr().getName()
430:                                    + ":" + functionError.getMessage(), -1));
431:                        }
432:                    } else if (error instanceof  FieldTemplateError) {
433:                        markers.add(new DroolsBuildMarker(error.getMessage(),
434:                                ((FieldTemplateError) error).getLine()));
435:                    } else if (error instanceof  FactTemplateError) {
436:                        markers.add(new DroolsBuildMarker(error.getMessage(),
437:                                ((FactTemplateError) error).getLine()));
438:                    } else if (error instanceof  ImportError) {
439:                        markers.add(new DroolsBuildMarker("ImportError: "
440:                                + error.getMessage()));
441:                    } else {
442:                        markers.add(new DroolsBuildMarker(
443:                                "Unknown DroolsError " + error.getClass()
444:                                        + ": " + error));
445:                    }
446:                }
447:            }
448:
449:            private void createMarker(final IResource res,
450:                    final String message, final int lineNumber) {
451:                try {
452:                    IWorkspaceRunnable r = new IWorkspaceRunnable() {
453:                        public void run(IProgressMonitor monitor)
454:                                throws CoreException {
455:                            IMarker marker = res
456:                                    .createMarker(IDroolsModelMarker.DROOLS_MODEL_PROBLEM_MARKER);
457:                            marker.setAttribute(IMarker.MESSAGE, message);
458:                            marker.setAttribute(IMarker.SEVERITY,
459:                                    IMarker.SEVERITY_ERROR);
460:                            marker
461:                                    .setAttribute(IMarker.LINE_NUMBER,
462:                                            lineNumber);
463:                        }
464:                    };
465:                    res.getWorkspace().run(r, null, IWorkspace.AVOID_UPDATE,
466:                            null);
467:                } catch (CoreException e) {
468:                    DroolsEclipsePlugin.log(e);
469:                }
470:            }
471:
472:            private void removeProblemsFor(IResource resource) {
473:                try {
474:                    if (resource != null && resource.exists()) {
475:                        resource.deleteMarkers(
476:                                IDroolsModelMarker.DROOLS_MODEL_PROBLEM_MARKER,
477:                                false, IResource.DEPTH_INFINITE);
478:                    }
479:                } catch (CoreException e) {
480:                    DroolsEclipsePlugin.log(e);
481:                }
482:            }
483:
484:            private IProject[] getRequiredProjects(IProject project) {
485:                IJavaProject javaProject = JavaCore.create(project);
486:                List projects = new ArrayList();
487:                try {
488:                    IClasspathEntry[] entries = javaProject
489:                            .getResolvedClasspath(true);
490:                    for (int i = 0, l = entries.length; i < l; i++) {
491:                        IClasspathEntry entry = entries[i];
492:                        if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
493:                            IProject p = project.getWorkspace().getRoot()
494:                                    .getProject(entry.getPath().lastSegment()); // missing projects are considered too
495:                            if (p != null && !projects.contains(p)) {
496:                                projects.add(p);
497:                            }
498:                        }
499:                    }
500:                } catch (JavaModelException e) {
501:                    return new IProject[0];
502:                }
503:                return (IProject[]) projects.toArray(new IProject[projects
504:                        .size()]);
505:            }
506:
507:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.