Source Code Cross Referenced for XMLMetaDataParser.java in  » Database-ORM » openjpa » org » apache » openjpa » lib » meta » 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 » Database ORM » openjpa » org.apache.openjpa.lib.meta 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.    
018:         */
019:        package org.apache.openjpa.lib.meta;
020:
021:        import java.io.File;
022:        import java.io.IOException;
023:        import java.io.InputStreamReader;
024:        import java.io.Reader;
025:        import java.net.URL;
026:        import java.security.AccessController;
027:        import java.util.ArrayList;
028:        import java.util.Collection;
029:        import java.util.Collections;
030:        import java.util.HashMap;
031:        import java.util.HashSet;
032:        import java.util.LinkedList;
033:        import java.util.List;
034:        import java.util.Map;
035:        import java.util.Set;
036:        import javax.xml.parsers.SAXParser;
037:
038:        import org.xml.sax.Attributes;
039:        import org.xml.sax.InputSource;
040:        import org.xml.sax.Locator;
041:        import org.xml.sax.SAXException;
042:        import org.xml.sax.SAXParseException;
043:        import org.xml.sax.ext.LexicalHandler;
044:        import org.xml.sax.helpers.DefaultHandler;
045:        import org.apache.openjpa.lib.log.Log;
046:        import org.apache.openjpa.lib.util.J2DoPrivHelper;
047:        import org.apache.openjpa.lib.util.JavaVersions;
048:        import org.apache.openjpa.lib.util.Localizer.Message;
049:        import org.apache.openjpa.lib.util.Localizer;
050:        import org.apache.openjpa.lib.xml.Commentable;
051:        import org.apache.openjpa.lib.xml.DocTypeReader;
052:        import org.apache.openjpa.lib.xml.Location;
053:        import org.apache.openjpa.lib.xml.XMLFactory;
054:
055:        /**
056:         * Custom SAX parser used by the system to quickly parse metadata files.
057:         * Subclasses should handle the processing of the content.
058:         *
059:         * @author Abe White
060:         * @nojavadoc
061:         */
062:        public abstract class XMLMetaDataParser extends DefaultHandler
063:                implements  LexicalHandler, MetaDataParser {
064:
065:            private static final Localizer _loc = Localizer
066:                    .forPackage(XMLMetaDataParser.class);
067:            private static boolean _schemaBug;
068:
069:            static {
070:                try {
071:                    // check for Xerces version 2.0.2 to see if we need to disable
072:                    // schema validation, which works around the bug reported at:
073:                    // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4708859
074:                    _schemaBug = "Xerces-J 2.0.2".equals(Class.forName(
075:                            "org.apache.xerces.impl.Version").getField(
076:                            "fVersion").get(null));
077:                } catch (Throwable t) {
078:                    // Xerces might not be available
079:                    _schemaBug = false;
080:                }
081:            }
082:
083:            // map of classloaders to sets of parsed locations, so that we don't parse
084:            // the same resource multiple times for the same class
085:            private Map _parsed = null;
086:
087:            private Log _log = null;
088:            private boolean _validating = true;
089:            private boolean _systemId = true;
090:            private boolean _caching = true;
091:            private boolean _parseText = true;
092:            private boolean _parseComments = true;
093:            private String _suffix = null;
094:            private ClassLoader _loader = null;
095:            private ClassLoader _curLoader = null;
096:
097:            // state for current parse
098:            private final Collection _curResults = new LinkedList();
099:            private List _results = null;
100:            private String _sourceName = null;
101:            private File _sourceFile = null;
102:            private StringBuffer _text = null;
103:            private List _comments = null;
104:            private Location _location = new Location();
105:            private LexicalHandler _lh = null;
106:            private int _depth = -1;
107:            private int _ignore = Integer.MAX_VALUE;
108:
109:            /**
110:             * Whether to parse element text.
111:             */
112:            public boolean getParseText() {
113:                return _parseText;
114:            }
115:
116:            /**
117:             * Whether to parse element text.
118:             */
119:            public void setParseText(boolean text) {
120:                _parseText = text;
121:            }
122:
123:            /**
124:             * Whether to parse element comments.
125:             */
126:            public boolean getParseComments() {
127:                return _parseComments;
128:            }
129:
130:            /**
131:             * Whether to parse element comments.
132:             */
133:            public void setParseComments(boolean comments) {
134:                _parseComments = comments;
135:            }
136:
137:            /**
138:             * The XML document location.
139:             */
140:            public Location getLocation() {
141:                return _location;
142:            }
143:
144:            /**
145:             * The lexical handler that should be registered with the SAX parser used
146:             * by this class. Since the <code>org.xml.sax.ext</code> package is not
147:             * a required part of SAX2, this handler might not be used by the parser.
148:             */
149:            public LexicalHandler getLexicalHandler() {
150:                return _lh;
151:            }
152:
153:            /**
154:             * The lexical handler that should be registered with the SAX parser used
155:             * by this class. Since the <code>org.xml.sax.ext</code> package is not
156:             * a required part of SAX2, this handler might not be used by the parser.
157:             */
158:            public void setLexicalHandler(LexicalHandler lh) {
159:                _lh = lh;
160:            }
161:
162:            /**
163:             * The XML document location.
164:             */
165:            public void setLocation(Location location) {
166:                _location = location;
167:            }
168:
169:            /**
170:             * Whether to use the source name as the XML system id.
171:             */
172:            public boolean getSourceIsSystemId() {
173:                return _systemId;
174:            }
175:
176:            /**
177:             * Whether to use the source name as the XML system id.
178:             */
179:            public void setSourceIsSystemId(boolean systemId) {
180:                _systemId = systemId;
181:            }
182:
183:            /**
184:             * Whether this is a validating parser.
185:             */
186:            public boolean isValidating() {
187:                return _validating;
188:            }
189:
190:            /**
191:             * Whether this is a validating parser.
192:             */
193:            public void setValidating(boolean validating) {
194:                _validating = validating;
195:            }
196:
197:            /**
198:             * Expected suffix for metadata resources, or null if unknown.
199:             */
200:            public String getSuffix() {
201:                return _suffix;
202:            }
203:
204:            /**
205:             * Expected suffix for metadata resources, or null if unknown.
206:             */
207:            public void setSuffix(String suffix) {
208:                _suffix = suffix;
209:            }
210:
211:            /**
212:             * Whether parsed resource names are cached to avoid duplicate parsing.
213:             */
214:            public boolean isCaching() {
215:                return _caching;
216:            }
217:
218:            /**
219:             * Whether parsed resource names are cached to avoid duplicate parsing.
220:             */
221:            public void setCaching(boolean caching) {
222:                _caching = caching;
223:                if (!caching)
224:                    clear();
225:            }
226:
227:            /**
228:             * The log to write to.
229:             */
230:            public Log getLog() {
231:                return _log;
232:            }
233:
234:            /**
235:             * The log to write to.
236:             */
237:            public void setLog(Log log) {
238:                _log = log;
239:            }
240:
241:            /**
242:             * Classloader to use for class name resolution.
243:             */
244:            public ClassLoader getClassLoader() {
245:                return _loader;
246:            }
247:
248:            /**
249:             * Classloader to use for class name resolution.
250:             */
251:            public void setClassLoader(ClassLoader loader) {
252:                _loader = loader;
253:            }
254:
255:            public List getResults() {
256:                if (_results == null)
257:                    return Collections.EMPTY_LIST;
258:                return _results;
259:            }
260:
261:            public void parse(String rsrc) throws IOException {
262:                if (rsrc != null)
263:                    parse(new ResourceMetaDataIterator(rsrc, _loader));
264:            }
265:
266:            public void parse(URL url) throws IOException {
267:                if (url != null)
268:                    parse(new URLMetaDataIterator(url));
269:            }
270:
271:            public void parse(File file) throws IOException {
272:                if (file == null)
273:                    return;
274:                if (!((Boolean) AccessController.doPrivileged(J2DoPrivHelper
275:                        .isDirectoryAction(file))).booleanValue())
276:                    parse(new FileMetaDataIterator(file));
277:                else {
278:                    String suff = (_suffix == null) ? "" : _suffix;
279:                    parse(new FileMetaDataIterator(file,
280:                            new SuffixMetaDataFilter(suff)));
281:                }
282:            }
283:
284:            public void parse(Class cls, boolean topDown) throws IOException {
285:                String suff = (_suffix == null) ? "" : _suffix;
286:                parse(new ClassMetaDataIterator(cls, suff, topDown), !topDown);
287:            }
288:
289:            public void parse(Reader xml, String sourceName) throws IOException {
290:                if (xml != null && (sourceName == null || !parsed(sourceName)))
291:                    parseNewResource(xml, sourceName);
292:            }
293:
294:            public void parse(MetaDataIterator itr) throws IOException {
295:                parse(itr, false);
296:            }
297:
298:            /**
299:             * Parse the resources returned by the given iterator, optionally stopping
300:             * when the first valid resource is found.
301:             */
302:            private void parse(MetaDataIterator itr, boolean stopFirst)
303:                    throws IOException {
304:                if (itr == null)
305:                    return;
306:                try {
307:                    String sourceName;
308:                    while (itr.hasNext()) {
309:                        sourceName = itr.next().toString();
310:                        if (parsed(sourceName)) {
311:                            if (stopFirst)
312:                                break;
313:                            continue;
314:                        }
315:
316:                        // individual files of the resource might already be parsed
317:                        _sourceFile = itr.getFile();
318:                        parseNewResource(new InputStreamReader(itr
319:                                .getInputStream()), sourceName);
320:                        if (stopFirst)
321:                            break;
322:                    }
323:                } finally {
324:                    itr.close();
325:                }
326:            }
327:
328:            /**
329:             * Parse a previously-unseen source. All parsing methods delegate
330:             * to this one.
331:             */
332:            protected void parseNewResource(Reader xml, String sourceName)
333:                    throws IOException {
334:                if (_log != null && _log.isTraceEnabled())
335:                    _log.trace(_loc.get("start-parse", sourceName));
336:
337:                // even if we want to validate, specify that it won't happen
338:                // if we have neither a DocType not a Schema
339:                Object schemaSource = getSchemaSource();
340:                if (schemaSource != null && _schemaBug) {
341:                    if (_log != null && _log.isTraceEnabled())
342:                        _log.trace(_loc.get("parser-schema-bug"));
343:                    schemaSource = null;
344:                }
345:                boolean validating = _validating
346:                        && (getDocType() != null || schemaSource != null);
347:
348:                // parse the metadata with a SAX parser
349:                try {
350:                    _sourceName = sourceName;
351:                    SAXParser parser = XMLFactory
352:                            .getSAXParser(validating, true);
353:                    Object schema = null;
354:                    if (validating) {
355:                        schema = schemaSource;
356:                        if (schema == null && getDocType() != null)
357:                            xml = new DocTypeReader(xml, getDocType());
358:                    }
359:
360:                    if (_parseComments || _lh != null)
361:                        parser
362:                                .setProperty(
363:                                        "http://xml.org/sax/properties/lexical-handler",
364:                                        this );
365:
366:                    if (schema != null) {
367:                        parser
368:                                .setProperty(
369:                                        "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
370:                                        "http://www.w3.org/2001/XMLSchema");
371:                        parser
372:                                .setProperty(
373:                                        "http://java.sun.com/xml/jaxp/properties/schemaSource",
374:                                        schema);
375:                    }
376:
377:                    InputSource is = new InputSource(xml);
378:                    if (_systemId && sourceName != null)
379:                        is.setSystemId(sourceName);
380:                    parser.parse(is, this );
381:                    finish();
382:                } catch (SAXException se) {
383:                    IOException ioe = new IOException(se.toString());
384:                    JavaVersions.initCause(ioe, se);
385:                    throw ioe;
386:                } finally {
387:                    reset();
388:                }
389:            }
390:
391:            /**
392:             * Return true if the given source is parsed. Otherwise, record that
393:             * it will be parsed.
394:             */
395:            protected boolean parsed(String src) {
396:                if (!_caching)
397:                    return false;
398:                if (_parsed == null)
399:                    _parsed = new HashMap();
400:
401:                ClassLoader loader = currentClassLoader();
402:                Set set = (Set) _parsed.get(loader);
403:                if (set == null) {
404:                    set = new HashSet();
405:                    _parsed.put(loader, set);
406:                }
407:                boolean added = set.add(src);
408:                if (!added && _log != null && _log.isTraceEnabled())
409:                    _log.trace(_loc.get("already-parsed", src));
410:                return !added;
411:            }
412:
413:            public void clear() {
414:                if (_log != null && _log.isTraceEnabled())
415:                    _log.trace(_loc.get("clear-parser", this ));
416:                if (_parsed != null)
417:                    _parsed.clear();
418:            }
419:
420:            public void error(SAXParseException se) throws SAXException {
421:                throw getException(se.toString());
422:            }
423:
424:            public void fatalError(SAXParseException se) throws SAXException {
425:                throw getException(se.toString());
426:            }
427:
428:            public void setDocumentLocator(Locator locator) {
429:                _location.setLocator(locator);
430:            }
431:
432:            public void startElement(String uri, String name, String qName,
433:                    Attributes attrs) throws SAXException {
434:                _depth++;
435:                if (_depth <= _ignore)
436:                    if (!startElement(qName, attrs))
437:                        ignoreContent(true);
438:            }
439:
440:            public void endElement(String uri, String name, String qName)
441:                    throws SAXException {
442:                if (_depth < _ignore)
443:                    endElement(qName);
444:                _text = null;
445:                if (_comments != null)
446:                    _comments.clear();
447:                if (_depth == _ignore)
448:                    _ignore = Integer.MAX_VALUE;
449:                _depth--;
450:            }
451:
452:            public void characters(char[] ch, int start, int length) {
453:                if (_parseText && _depth <= _ignore) {
454:                    if (_text == null)
455:                        _text = new StringBuffer();
456:                    _text.append(ch, start, length);
457:                }
458:            }
459:
460:            public void comment(char[] ch, int start, int length)
461:                    throws SAXException {
462:                if (_parseComments && _depth <= _ignore) {
463:                    if (_comments == null)
464:                        _comments = new ArrayList(3);
465:                    _comments.add(String.valueOf(ch, start, length));
466:                }
467:                if (_lh != null)
468:                    _lh.comment(ch, start, length);
469:            }
470:
471:            public void startCDATA() throws SAXException {
472:                if (_lh != null)
473:                    _lh.startCDATA();
474:            }
475:
476:            public void endCDATA() throws SAXException {
477:                if (_lh != null)
478:                    _lh.endCDATA();
479:            }
480:
481:            public void startDTD(String name, String publicId, String systemId)
482:                    throws SAXException {
483:                if (_lh != null)
484:                    _lh.startDTD(name, publicId, systemId);
485:            }
486:
487:            public void endDTD() throws SAXException {
488:                if (_lh != null)
489:                    _lh.endDTD();
490:            }
491:
492:            public void startEntity(String name) throws SAXException {
493:                if (_lh != null)
494:                    _lh.startEntity(name);
495:            }
496:
497:            public void endEntity(String name) throws SAXException {
498:                if (_lh != null)
499:                    _lh.endEntity(name);
500:            }
501:
502:            /**
503:             * Override this method marking the start of some element. If this method
504:             * returns false, the content of the element and the end element event will
505:             * be ignored.
506:             */
507:            protected abstract boolean startElement(String name,
508:                    Attributes attrs) throws SAXException;
509:
510:            /**
511:             * Override this method marking the end of some element.
512:             */
513:            protected abstract void endElement(String name) throws SAXException;
514:
515:            /**
516:             * Add a result to be returned from the current parse.
517:             */
518:            protected void addResult(Object result) {
519:                if (_log != null && _log.isTraceEnabled())
520:                    _log.trace(_loc.get("add-result", result));
521:                _curResults.add(result);
522:            }
523:
524:            /**
525:             * Override this method to finish up after a parse; this is only
526:             * called if no errors are encountered during parsing. Subclasses should
527:             * call <code>super.finish()</code> to resolve superclass state.
528:             */
529:            protected void finish() {
530:                if (_log != null && _log.isTraceEnabled())
531:                    _log.trace(_loc.get("end-parse", getSourceName()));
532:                _results = new ArrayList(_curResults);
533:            }
534:
535:            /**
536:             * Override this method to clear any state and ready the parser for
537:             * a new document. Subclasses should call
538:             * <code>super.reset()</code> to clear superclass state.
539:             */
540:            protected void reset() {
541:                _curResults.clear();
542:                _curLoader = null;
543:                _sourceName = null;
544:                _sourceFile = null;
545:                _depth = -1;
546:                _ignore = Integer.MAX_VALUE;
547:                if (_comments != null)
548:                    _comments.clear();
549:            }
550:
551:            /**
552:             * Implement to return the XML schema source for the document. Returns
553:             * null by default. May return:
554:             * <ul>
555:             * <li><code>String</code> pointing to schema URI.</li>
556:             * <li><code>InputStream</code> containing schema contents.</li>
557:             * <li><code>InputSource</code> containing schema contents.</li>
558:             * <li><code>File</code> containing schema contents.</li>
559:             * <li>Array of any of the above elements.</li>
560:             * </ul>
561:             */
562:            protected Object getSchemaSource() throws IOException {
563:                return null;
564:            }
565:
566:            /**
567:             * Override this method to return any <code>DOCTYPE</code> declaration
568:             * that should be dynamically included in xml documents that will be
569:             * validated. Returns null by default.
570:             */
571:            protected Reader getDocType() throws IOException {
572:                return null;
573:            }
574:
575:            /**
576:             * Return the name of the source file being parsed.
577:             */
578:            protected String getSourceName() {
579:                return _sourceName;
580:            }
581:
582:            /**
583:             * Return the file of the source being parsed.
584:             */
585:            protected File getSourceFile() {
586:                return _sourceFile;
587:            }
588:
589:            /**
590:             * Add current comments to the given entity. By default, assumes entity
591:             * is {@link Commentable}.
592:             */
593:            protected void addComments(Object obj) {
594:                String[] comments = currentComments();
595:                if (comments.length > 0 && obj instanceof  Commentable)
596:                    ((Commentable) obj).setComments(comments);
597:            }
598:
599:            /**
600:             * Array of comments for the current node, or empty array if none.
601:             */
602:            protected String[] currentComments() {
603:                if (_comments == null || _comments.isEmpty())
604:                    return Commentable.EMPTY_COMMENTS;
605:                return (String[]) _comments
606:                        .toArray(new String[_comments.size()]);
607:            }
608:
609:            /**
610:             * Return the text value within the current node.
611:             */
612:            protected String currentText() {
613:                if (_text == null)
614:                    return "";
615:                return _text.toString().trim();
616:            }
617:
618:            /**
619:             * Return the current location within the source file.
620:             */
621:            protected String currentLocation() {
622:                return " [" + _loc.get("loc-prefix") + _location.getLocation()
623:                        + "]";
624:            }
625:
626:            /**
627:             * Return the parse depth. Within the root element, the depth is 0,
628:             * within the first nested element, it is 1, and so forth.
629:             */
630:            protected int currentDepth() {
631:                return _depth;
632:            }
633:
634:            /**
635:             * Return the class loader to use when resolving resources and loading
636:             * classes.
637:             */
638:            protected ClassLoader currentClassLoader() {
639:                if (_loader != null)
640:                    return _loader;
641:                if (_curLoader == null)
642:                    _curLoader = (ClassLoader) AccessController
643:                            .doPrivileged(J2DoPrivHelper
644:                                    .getContextClassLoaderAction());
645:                return _curLoader;
646:            }
647:
648:            /**
649:             * Ignore all content below the current element.
650:             *
651:             * @param ignoreEnd whether to ignore the end element event
652:             */
653:            protected void ignoreContent(boolean ignoreEnd) {
654:                _ignore = _depth;
655:                if (!ignoreEnd)
656:                    _ignore++;
657:            }
658:
659:            /**
660:             * Returns a SAXException with the source file name and the given error
661:             * message.
662:             */
663:            protected SAXException getException(String msg) {
664:                return new SAXException(getSourceName() + currentLocation()
665:                        + ": " + msg);
666:            }
667:
668:            /**
669:             * Returns a SAXException with the source file name and the given error
670:             * message.
671:             */
672:            protected SAXException getException(Message msg) {
673:                return new SAXException(getSourceName() + currentLocation()
674:                        + ": " + msg.getMessage());
675:            }
676:
677:            /**
678:             * Returns a SAXException with the source file name and the given error
679:             * message.
680:             */
681:            protected SAXException getException(Message msg, Throwable cause) {
682:                if (cause != null && _log != null && _log.isTraceEnabled())
683:                    _log.trace(_loc.get("sax-exception", getSourceName(),
684:                            _location.getLocation()), cause);
685:                SAXException e = new SAXException(getSourceName()
686:                        + currentLocation() + ": " + msg + " [" + cause + "]");
687:                e.initCause(cause);
688:                return e;
689:            }
690:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.