commons-discovery-0.5/0000755000175000017500000000000011643422202014726 5ustar drazzibdrazzibcommons-discovery-0.5/build.properties.sample0000644000175000017500000000274511550346276021450 0ustar drazzibdrazzib# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ########################################################################## # Sample Ant build.properties file # # This setup assumes dependent jars are in a local maven 2 repository. # However the jars are located, the properties ending in ".jar" need # expand to full paths to the jars. ########################################################################## # Repository base path - unnecessary if full jar paths are provided below repository=${user.home}/.m2/repository # JUnit junit.home=${repository}/junit/junit/4.8.2 junit.jar=${junit.home}/junit-4.8.2.jar # Commons logging logger.home=${repository}/commons-logging/commons-logging/1.1.1 logger.jar=${logger.home}/commons-logging-1.1.1.jarcommons-discovery-0.5/pom.xml0000644000175000017500000001771511556060015016261 0ustar drazzibdrazzib org.apache.commons commons-parent 20 4.0.0 commons-discovery commons-discovery 0.5 Commons Discovery 2002 The Apache Commons Discovery component is about discovering, or finding, implementations for pluggable interfaces. http://commons.apache.org/discovery/ jira http://issues.apache.org/jira/browse/DISCOVERY scm:svn:http://svn.apache.org/repos/asf/commons/proper/discovery/tags/DISCOVERY_0_5_RC2 scm:svn:https://svn.apache.org/repos/asf/commons/proper/discovery/tags/DISCOVERY_0_5_RC2 http://svn.apache.org/viewvc/commons/proper/discovery/tags/DISCOVERY_0_5_RC2 Richard Sitze rsitze Craig R. McClanahan craigmcc Costin Manolache costin James Strachan jstrachan jstrachan@apache.org SpiritSoft, Inc. Matthew Hawthorne matth matth@apache.org Davanum Srinivas dims dims@apache.org Rory Winston rwinston rwinston@eircom.net Robert Burrell Donkin rdonkin rdonkin@apache.org Simone Tripodi simonetripodi simonetripodi@apache.org commons-logging commons-logging 1.1.1 junit junit 4.8.2 test discovery 0.5 (minium JDK 1.5) RC2 DISCOVERY 12310472 1.5 1.5 apache.website Apache Commons Site ${commons.deployment.protocol}://people.apache.org/www/commons.apache.org/discovery src/java src/test ${basedir}/src/test **/*.properties **/testResource META-INF/** org.apache.maven.plugins maven-surefire-plugin **/TestAll.java ${basedir}/src/testAlt1 ${basedir}/src/testAlt2 maven-assembly-plugin package single src/assembly/bin.xml src/assembly/src.xml gnu org.apache.maven.plugins maven-changes-plugin 2.3 ${basedir}/src/changes/changes.xml %URL%/%ISSUE% changes-report org.apache.maven.plugins maven-checkstyle-plugin 2.1 ${basedir}/checkstyle.xml false org.codehaus.mojo findbugs-maven-plugin 2.3.1 Normal Default ${basedir}/findbugs-exclude-filter.xml rc apache.website Apache Commons Release Candidate Staging Site ${commons.deployment.protocol}://people.apache.org/www/people.apache.org/builds/commons/${commons.componentid}/${commons.release.version}/${commons.rc.version}/site commons-discovery-0.5/doap_discovery.rdf0000644000175000017500000000443711546071675020465 0ustar drazzibdrazzib Apache Commons Discovery Java Commons Discovery Commons Discovery commons-discovery 2003-04-15 0.2 commons-discovery-0.5/STATUS.html0000644000175000017500000000750510653533705016661 0ustar drazzibdrazzib Status File for Apache Commons "Discovery" Component

The Apache Commons Discovery Component

$Id: STATUS.html 561230 2007-07-31 04:17:09Z rahul $
[Introduction] [Dependencies] [Release Info] [Committers] [Action Items]

1. INTRODUCTION

The commons-discovery package provides best-practice algorithms for discovering (locating) implementations of Java interfaces. It includes support for locating/loading properties files, caching-by-classloaders, and attempts using various classloaders.

commons-discovery was heavily influenced by code originally integrated into commons-logging, which was likely to have been based on experience/projects related to the committers of that component.

Goals:

Non-goals:

2. DEPENDENCIES

The Discovery component is dependent upon the following external components for compilation:

The user must ensure that any service that they wish to discover (use) are 'discoverable' by the application environments classloaders (in the classpath, war/ear/jar file, etc) when they use this component.

3. RELEASE INFO

Current Release: 0.2, CVS Repository Only

Planned Next Release: RC1

4. COMMITTERS

The following individuals are the primary developers and maintainers of this component. Developers who plan to use Discovery in their own projects are encouraged to collaborate on the future development of this component to ensure that it continues to meet a variety of needs.

5. ACTION ITEMS

TO DO List: see also TODO file

Action Item Volunteer
commons-discovery-0.5/PROPOSAL.html0000644000175000017500000001030110653172436017061 0ustar drazzibdrazzib Proposal for Service Discovery

Proposal for Service Discovery Package

(0) Rationale

The Discovery Component is about discovering, or finding, implementations for pluggable interfaces. It provides facilities intantiating classes in general, and for lifecycle management of singleton (factory) classes.

Fundamentally, Discovery locates classes that implement a given Java interface. The discovery pattern, though not necessarily this package, is used in many projects including JAXP (SaxParserFactory and others) and commons-logging (LogFactory). By extracting this pattern, other projects can (re)use it and take advantage of improvements to the pattern as Discovery evolves.

Discovery improves over previous implementations by establishing facilities for working within managed environments. These allow configuration and property overrides without appealing to the global System properties (which are scoped across an entire JVM).

(1) Scope of the Package

This is not indended to be a replacement to be used strictly by the user, but rather a replacement to be used directly by projects. Use by the user is also reasonable, but limited due to 'keeping this simple'. In particular, there is no configuration for this discovery service, it relies soley on usage patterns.

Given a java.lang.Class parameter 'package.Class' that represents a fundamental service as either an interface, an abstract class (or even a regular class), find an implementation of that class:

In all cases, verify that the discovered implementation implements 'package.Class'.

The package should :

(1.5) Interaction With Other Packages

Services relies on:

(2) Required Jakarta-Commons Resources

(4) Initial Committers

The initial committers on the Service Discovery component shall be:

commons-discovery-0.5/build.xml0000644000175000017500000002074311036753301016560 0ustar drazzibdrazzib commons-discovery-0.5/RELEASE-NOTES.txt0000644000175000017500000000407111556040267017451 0ustar drazzibdrazzib$Id: RELEASE-NOTES.txt 1097166 2011-04-27 16:13:43Z sebb $ Commons Discovery Package Version 0.5 Release Notes INTRODUCTION ============ This is an APIs update and maintenance release. New projects are encouraged to use this release of discovery. IMPORTANT NOTES =============== BREAKING CHANGES: * The minimum JDK requirement is now JDK 1.5. The provided binaries will not work on lower JDKs. The source has been updated to leverage Generics and other JDK 1.5 features where possible, and requires JDK 1.5 to compile. Dependencies ============= Commons Discovery depends on Commons Logging. It is built against version 1.1.1. NEW FEATURES ============= * Discovery APIs use Java5 Generics. BUGS FROM PREVIOUS RELEASE ========================= JIRA Issues Addressed --------------------- * DISCOVERY-3 (https://issues.apache.org/jira/browse/DISCOVERY-3) * DISCOVERY-6 (https://issues.apache.org/jira/browse/DISCOVERY-6) * DISCOVERY-7 (https://issues.apache.org/jira/browse/DISCOVERY-7) * DISCOVERY-9 (https://issues.apache.org/jira/browse/DISCOVERY-9) * DISCOVERY-11 (https://issues.apache.org/jira/browse/DISCOVERY-11) * DISCOVERY-12 (https://issues.apache.org/jira/browse/DISCOVERY-12) * DISCOVERY-14 (https://issues.apache.org/jira/browse/DISCOVERY-14) * DISCOVERY-15 (https://issues.apache.org/jira/browse/DISCOVERY-15) * DISCOVERY-16 (https://issues.apache.org/jira/browse/DISCOVERY-16) * DISCOVERY-17 (https://issues.apache.org/jira/browse/DISCOVERY-17) Known bugs/limitations --------------------- resource.classes.DiscoverClasses doesn't work with Oracle embedded JVM in DBMS, see DISCOVERY-13 (https://issues.apache.org/jira/browse/DISCOVERY-13) DEPRECATIONS ============ Classes in org.apache.commons.discovery.log package have been deprecated, depending on Apache Commons Logging 1.1.1 there is no more circular dependency between Apache Commons Discovery and Apache Commons Logging. setLog(org.apache.commons.logging.Log) methods have been deprecated too, they are not thread-safe. commons-discovery-0.5/LICENSE.txt0000644000175000017500000002613610210071235016554 0ustar drazzibdrazzib Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. commons-discovery-0.5/findbugs-exclude-filter.xml0000644000175000017500000000230311550303234022161 0ustar drazzibdrazzib commons-discovery-0.5/checkstyle.xml0000644000175000017500000000306011547423734017623 0ustar drazzibdrazzib commons-discovery-0.5/NOTICE.txt0000644000175000017500000000026211546067144016464 0ustar drazzibdrazzibApache Commons Discovery Copyright 2002-2011 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). commons-discovery-0.5/src/0000755000175000017500000000000011643422202015515 5ustar drazzibdrazzibcommons-discovery-0.5/src/assembly/0000755000175000017500000000000011643422200017332 5ustar drazzibdrazzibcommons-discovery-0.5/src/assembly/bin.xml0000644000175000017500000000356411550141364020642 0ustar drazzibdrazzib bin tar.gz zip false LICENSE.txt NOTICE.txt RELEASE-NOTES.txt target *.jar target/site/apidocs apidocs commons-discovery-0.5/src/assembly/src.xml0000644000175000017500000000355411550303115020652 0ustar drazzibdrazzib src tar.gz zip ${project.artifactId}-${commons.release.version}-src checkstyle.xml LICENSE.txt NOTICE.txt pom.xml PROPOSAL.html RELEASE-NOTES.txt TODO findbugs-exclude-filter.xml src commons-discovery-0.5/src/changes/0000755000175000017500000000000011643422202017125 5ustar drazzibdrazzibcommons-discovery-0.5/src/changes/changes.xml0000644000175000017500000000573511550161110021264 0ustar drazzibdrazzib Commons Discovery Changes Enumeration in Service class is broken. [discovery] Doesn't work with ClassLoaders that do not support getResource() Discovery failed to load an inner class. Documentation of other use cases. Service.providers Enumeration does not catch and discard UnsatisfiedLinkErrors and ExceptionInInitializerErrors. SPI implementation class searching logic has some issues: it discards all errors; it only considers first className in supplied classNames array. Problem with Oracle JVM classLoader. Moved to Java5 APIs, used Generics. Custom org.apache.commons.discovery.log.Log implementation replaced by default commons-logging behavior. The setLog() methods are not thread-safe and should be deprecated. Enumeration returned by Service.providers has a broken behavior. commons-discovery-0.5/src/media/0000755000175000017500000000000011643422200016572 5ustar drazzibdrazzibcommons-discovery-0.5/src/media/logo.xcf0000644000175000017500000005470310006021306020237 0ustar drazzibdrazzibgimp xcf file,dBB&/ gimp-commentCreated with The GIMP¦D+:9X,¹, Text Layer#3ÿ     ^0%W¹,s,8¹,‹¾ j   ûª8/ûqÆUþâÿÿþ8+üUâÿÿþUþUÿÿþª*ýÆâÿÿþUþ8ÿÿþ,ýâÿÿþUúªÿÿâ-þªÿÿþUý8U/þªÿÿþU9þªÿÿþU9þªÿÿþU9þªÿÿþU9þªÿÿþU2þUUþªÿÿþU þ8 þUUýqâÿÿüªÿÿþUúqÆÿªýqâÿÿûÆUªUý8ÆóâÿâUqÿâÆÿÿþUü8qÆÿÿþªóªÿâqqâÿÿUûÆÿÆû8ÿÿªýâÿÿþUªÿþªûÿÿûâÿUûUâÿqûâÿâþ8ÿÿþUþÿÿþªÿþªüqÿªûÿÿªûÆÿÿ8þÆÿÿþUþUÿÿþªûUÿÿªýâªûâÿÿû8ÿÿâþªÿÿþUþUÿÿþªþUÿÿþýqªûqÿÿûÆÿÿªþªÿÿþUþUÿÿþªþ8ÿÿýÆý8qûâÿÿUþÿÿþqþªÿÿþUþUÿÿþªþÆÿÿýâq þ8ÿÿþUÿÿþUþªÿÿþUþUÿÿþªþ8ÿÿýâqþUÿÿþÿÿþUþªÿÿþUþUÿÿþªýUâÿÿýÆ8þªÿÿþªÿÿþUþªÿÿþUþUÿÿþªýÆÿÿýÆþªÿÿþªÿÿþqþªÿÿþUþUÿÿþª ýqâÿÿþUþªÿÿþUþªÿÿþªþªÿÿþUþUÿÿþª ýqâÿÿþUþªÿÿþþÿÿþâþªÿÿþUþUÿÿþªý8þÿÿþâþqÿÿþâþUÿÿþ8þªÿÿþUþUÿÿþªýUªþUÿÿûU8ÿÿþqÿþÆþªÿÿþUþUÿÿþªýUÿþÿÿþUþâÿÿûÿÿþqþâÿÿþUþUÿÿþªüUÿqþUÿÿþ8þqÿÿúâ8âÿÿþþªÿÿýÆþUÿÿþªüUÿâûqÿÿâþÆÿÿþUÿÿ÷âUUââÆÿÿþqþqÿÿþªûUÿÿªûâÿÿUýâÿÿýUâÿÿüâªÿÿüÆqþÆÿÿþþUÿÿõâUUÆÿÿUýâÿÿýÿÿøªÿ8ûUÆÿÿôâªUUªUUªÿÿýª8üqâÿþ8UUþ8þU UþþUUþ   ÁUþ8þ8UUþþ8UUþ8þUUþÿýª8 ý8ªÿÿý8ý8Æÿÿýª8ýªÿÿýúUªÿÿþªõÆÿâqUÆÿÿþþªÿÿþqûUÿÿU þâÿÿþúâÿâþªÿÿýâþâÿÿþªüUÿÆ þÿÿúâÿÿ8þªÿÿþÆþqÿÿþâüÿqþ8þ8ÿÿþ8ûÆÿÿÆþâÿÿþþâÿÿþUâþâûªÿÿªþ8ÿÿþUþqÿÿþþÿÿþÆüUÿýqÿUþªÿÿþþÿÿþqþÿÿþüÆÿýÆÿ ÿ þÆÿÿþªþªÿÿþüÿªÿ þ8ÿÿ þªÿÿþ8ÿÿþâüÿ8üUÿÿ þUÿÿ þUÿÿþÆÿÿþqâüUÿÿ þUÿÿþ þUÿÿþqÿÿþÆüUÿqüUÿÿ þUÿÿþU þUÿÿþâÿÿù8ªÿüUÿÿ þÿÿþq þUÿÿþÆþqÿÿúÿüUÿÿþÿþª þUÿÿþþÿÿûqÿ8üUÿÿýUªþªÿÿ þªÿÿþ8þÿÿüqâÆÿüUÿþ8ÿÿþqûÆÿÿÆ þ8ÿÿüâÿqýÆÿüUÿþªÿÿþâþÿÿþ8 þÆÿÿ ûqÿªUûUÆÿÆýâÿÿþqûªÿÿU þUÿÿþ þÆÿÿýâýâÿÿþUûUÿÿq ûâÿÿ8 þÿÿýªýªÿÿö88ªÿâUüqÿÆ ÿýÆ8 ý8ªÿÿýâqüÿ8 Uþ8UUþ8Ž Ì Ì ÌxþUUþ Uü8UUþUþýqâÿÿýâqøUªÿUqÿÿ8þÆÿÿüªqýUªÿÿôÆUââUUqÆÿÿýâü8âÿÿüUªÿÿûªqÿÿþqöªÿªUÿâþªÿÿýâýƪÿÿúUqÿªâÿÿþªþâÿÿþª÷âÿ8ÿÿþâÿÿþþÿÿöâÆÿÿUþqÿÿþâü8ÿÆýÿªþÿÿþªÿÿþýU8ÿþqüªÿqýÿUþUÿÿþUþªÿÿþ þÿÿþÆÿþýÿqUUþqÿÿþªþªÿÿþU þÿÿþ8üUÿªÿþªþªÿÿþU þÿÿþÆüªÿ8þÿþªÿÿþU þÿÿþ8ýÿâþÿþªÿÿþU þÆÿÿþüqÿýÿ8þªÿÿþU þ8ÿÿþüÆÿýÿUþªÿÿþU þÆÿÿùÿÆýÿªþªÿÿþU þ8ÿÿúqÿqÿ ýUþªÿÿþUþÆÿÿûqÆÿÿþq ýâUþªÿÿþUþqÿÿûâÿªÿþýªÆþªÿÿþUþâÿÿüâÿ8ÿýâüªÿ8þªÿÿþUþUÿÿþâÿýâqû8ÆÿqþªÿÿþUþÆÿÿþþâÿÿªûâÿÿªþªÿÿþqþUÿÿþýâÿÿþUþÿÿþâÿþÆ ýqâÿÿüâýqªÿÿûâªU üªÿU þUUþ Uþ ÿ5üUÿ4üÆÿ83üÿÆ4üªÿq.þüUÿâ-þUÿÿùÆUqÿÿU-þâÿÿþª.þÆÿÿýâ.þUÿÿýÆ0úªªU\. É<Drop-Shadow#2h     [-&îÉ< *ö+É<&° ô*7£/þþ(öô %ù  î  #ã    !â ""  )./+#  à )1550( ,8?@;0# à  -:EKKD7)'6DNOH;+à(9JYa`WG5%+@;2& !)/355÷41,$ õ)17:;;Ü?FTf{˜–‡nS:+%(1>KSUOC3$#/8>AA?>>÷?=7.$à  ,7@DDA><>FTg|™—ˆoS<-)/4..6E[t‰–•‡oS<.+3D[p€…}jQ:)#'4FWbd^TH@< $6HW_^TF7+$$+;Rlƒ‘’…mR;,)1CZr„Š‚oU=,&+:M_kngZLA:9:;95.))/-AUchbTB0""3Je}ƒlQ9*&.@Xq„‹„qX?.'-VkvtgQ:%(?[u‡‹€jO7&!'9QlŠ„rX?,$(5I_r}€|rfZOF>6/,.7G .F_s}yiQ8# &=Xs…ŠiO6% &7Pj‰„qX>+!#.AVjyƒ~wmbVK@724=N2Key‚}kR8" %)&6I]nz‚„‚}tj]PE==FV4Oi~‡oU:$ %'&=Xr…ŠjO6%%6Ni‰„qX=($1?M[ht}„‡†€ug\UXd5Ok‚ŠzaF.(?Zt†‹kP7& &6Oi‰„rX>)!*4?IUanzƒ‰‰‚wja`i2Lh€ŽŽjP8&-C^w‰ƒmR9(!'7Oj‰„rX>*#)/5;CN[jy…‹‰€tiej -Fb{Œ‡u]E3&#'5Jc|Œ†pV=+$)9Pk€‰„rY@,!"(.1247>JZl|‡Š„xleh (?Zs‡kVC614@Sk”‰tZA/(,;SlІt[B/%$)0675225>L_q…vi`a !6Nh~‹Ž†xfUICDM]r…’”Šv\E3,/>Um‹†t\D2))/8>@<7339EVhv}znaWVÂ+AZp‰‰€tf[TSYfv†‘‡t\F6/3AVn‰…t]F4,,4=EGD>869CQ`mrnbTJH !4I_r~ƒzqg`^ait€‡‡}lXD615BVk}„€q\F5-.5?GJHC=:CJQUTMB5,)Ã(7GU`fhfb]XVWZ]_]VJ>2+*/:IXdjg\M=/('+3:?@?<;HOSSQMHEDEFFD>6-&""'0<6.&#%&''())(%! Ð "%'&%" #'('$÷ Ò     ÷ ñ í üù ûûûü  H üþþüüþø  øù  ó  û ð  ø €          $'(%    !$'*,.-+&  "%')+,-,)% %/7<=91'  &*  %*-037;>@>8/% "(-013479<=;70($1?KSTOD6' *38'.3579;@FLQQLB4'!)28;;€°:<>CHLMKD;/% +;L\gjdWE2"'4>C",5;>>=<=BJT\_\RC3' &/:BFFC?<HT`gf]N>1*,4@KRRNF>869ALXcjjbUE6,*1AUk|…s\D."/=HL0Ri}ˆˆ{fL5$$1?HK;IUZWM?2)%)3AP[_[QE==DR`ii`Q@0%!#+9L`r~€weP>209Kbx‡ŠmT<*! (4?FGFV`bZL:+ &2@KPOHA>CO_ntqcO:( .BYo€‡‚s]F5/3BXo‰…t]E2'&,6?DAP`ih\I5$$/8=>;97bqwq_H0  ")7Jbyˆ‰}fJ0 )A]x‹‘ˆtY?-%)8Nfz…„xgTGA@A@;2ix}ubJ1 %5Kf~Ž€hL1 %L^q€‰Œ‰ƒ{ri`XNC7,#'5FWdjiaUI>769?GMOKA4% )+-9J\ly€‚€{tkaVJ=0$&4CPY\YSJC=;2&#0;EKLJFA=:99¶72+"  !,6:7/##/>:3) "'(%71(!',16;@CED?7,"",5=ABA@ADHJJHEDFKQVVQF9*$-451(B:/%!(/48KUZ[XVUWZ\\XTRU[dklfYH5$ ,7?@:0H?3)""&.6<@BCFLS]ejibUE6-+1>O_lrqmgddege`[Y\dpz}xiU>*$2?GG@3I?4+'*2JSVSNIGKTap}ƒucPA;@Ody‰‚tia][XSNMS_p‹Š~hO7%,:FKH>/@7/-1=LY`a[SKGIQ^o}‡†|kWF>BQf}Ž•‚p`TMIEA>>ESgz‰ŒƒpW?+ $/=GJD9*:1,-7FXfljaVLGGNZix‚ƒ{kWF>AOe}Ž•Ž~hTE;51.-.6FZqƒ‹‡xaH4'$)4?FG?2$4,)/0,09AFC9,.('0AVkx{tgWJB@BIS\cd_TE949H_w‰†rX?,+@Xp‰ƒt_J<68>DE?4&)$&1E\q~~ueSE;77;AHLMIA7/-4E\u‡Œ‚mS9$ !4Lez†‡|kXIAADFC:. $ $2G`u€€taM=2,*,/3674/)%&/BZs…Š€kP6  *@Yp‚ˆ„wfWNKJHA6(#2Ibxƒt_I6)!"$%$!"-AZs„‰iN4 !5Mf{‡‰tf[UPI?1# !1Icy…„v`I4%€R!-AZs„‰iN3 +AZr„ŒŠui_UJ<- /Gby‡‡{eM6%".AZs„‰iN3 "6Oh}‹‹‚uhYI8(,D_xˆ‹‚nV?, $0C[s„‰iN3,C\uˆ’“Œo\H5# (?Zt‡Ž‰zdN:+""%%$$(2D\t…Š€jO4 #7Pj–’…r\E0  #8Rm‚Ž…s_L=3,**,..-*)+5F^u‡‹lQ6 -D_w‹”’†rZB, 0Hby‰ŒqaRG@<;;:73.+-6G_v‡‹‚mR8"  $9RlŽ‚nU<&  'MTRH8' Ù '/7<5-# ì #0>IMI>. Ä "&(('$  $()'$  ",7BIIB5&Ç      %+19AGIE;- ø  ú ù  ã  ",4:?DIMNJB5' ûóþè$1?JQVYZXSJ=/    è -?P^gkkg`UG8('è "4H\kuxumaRA0! 'é "5J^mwxsiZI7'(é 0CVdlmg\L<+ (ê'7FRYYSH;- *ì (3=:4," &Å +7BJOTX\_^WI7%   -:CJOSWZ]]ZQE5% #1@LÄ &8HTZ\\]bkw€€u_D*  )bŒeD( ;e‘±¹§Q*=eŠ ƒ]9 &Bh‘³Á¸šoD$*Ky©Ì0V}–”zT0 )Lt”¡”rI'.T€£¯wK'*Mz¦Ãȳ‹\3 >m¡È Bm“£”oD"  3QlxoV7 >j˜µµ˜i<  8d•½ÏÅ¢rC  6f›Ä+S¤ª‘d8 0BJE5"'M~ªÀ·‘_2Ü)Q„³ÏÏ´…R) 3c™Â5b‘¯­\0è  $" /[Ž¸È·ŒX,Ý Cu¨ËÔ¿“^1 2b™Â ?o·¯ŠX,é   6e™Á̸‹V*Ý8ižÇÖÆh8 2b™Á !Gx¦½²ŠW+ê ;l¡ÇѺŒW+Ý1_•ÁÕÊ£n<2b™Á $L­Â¶ŽZ-ï >p¤ÊÔ¾Z-Þ,Y½Óʤp>2b™Á%N‚°Ç¼•a3î >o¤Ë××a2Þ*U‹ºÑÈ¢n<2b™Á %M±Êßl< ì ;k ÉØÉ j:Ý)TЏÎÃh8 2b™Á "I|­Ëʬ}K&ë 6c˜ÄØÎªvD Ü+V‹·Ê¼“_1 2b™Á Bs¦ÉÑ»‘a7 é 0YŒ»ÔÒ´ƒP(Û.[·Ä±†S) 2b™Á8g›ÃÔɨ{O- é !,/*)K|­ÍÓ¾“`3€5c”·¼¢uE! 2b™Á-WŠ·ÑÓ¾špJ. )7@?2" =išÀÐÅ¢rC!  @nš³¯Ž`6 2b™Â !Et¤ÇÖÏ·”pQ;-%#%,7EPQF2-S¬ÆÈ°†X1 *NzªšuJ&3c™Â3[гÎÖÍ·›gVLHJQZabXC+ m ÆÂ*Kr˜·ÊÑÏÆ»°¦ž˜…s[@' -LoŽ¢¤•|aI:35>Ocu|t]@% )Jw¥ÆÃ .Mp‘«½ÅÇĽ´ªw^C*  -Ig€†veWPPV_hleT<% !8X~¤¾× -Gd~“¢ª¬©¡”„oX?)  )?Vjvyume`]]î[SF4!  )A\z•¦é &:Napz~|uiYG4" Þ  1AOY]][WSNH@5( (<82+# +7AIMî !##  í   ö !$&ñ  ð ÷  ÷þþþ?   @þ þð ó Ç      !! €)   ! )&(4>DE@6(  ,8AFFA6) !(*% ,8AFD=2# PI:+%*8HYgqtoaM6#,=N^ksuoaM5  (6EOOE4'%-m¡ÆÑ½“`4  #5Y‡±Ëʰ…W2 3Y‡²ÌÍ´‹]6Ķ–nI, 6V~¤¾ÆºœuO1 6U}£½Ä¶—pL2%$.DeŒ®ÂÁ¬‰b?&&Ad‹®ÃıhEª¡‹mO5!(>Zy”§¬¤sU:&)>Zx”¦ª¡‹nR<0/9Lg„›©¨šcF-.Geƒœ©ªž†iL€zm[F1!'9Nbs~|q_K7&'9Nbs}€zm[I90/7EWiw~vgT?,,@Viw€ykXDNLF<1$)5@HMOMG?4')5@HMNLF=3*%$)1;DJNNJC9-  -:DJNNKE;0&%# !$&&Ã$  !$&&%# #%&&%" "%&&%#  ó  õ  ô  ü þþþþþ>   Aøþüí  ù  ù á  " ì   Ý   "$0;CGE>2# Ä #+17;=><7/&  $+.+"%1$ .Hf…Ÿ¯¯ž„mceo|‹šªµ¶acgn{§ºÀ±Ža6 %A`y„}kTA516CXr¡§„a?$1Mp–¶Êʸ›€nfejt„›²ÁOHEHTl®ÃÁ¤wG"  <`“yZ='&9Uw™°¶¦†^9)Di”»ÓÖã‚fTJHN_z»6)$&1Jp›½Ç³ˆU+ 1Wœ¢ŽjD' 7Z„©¿¾¦~R.4Z‰¶ÒÖÂuR:,'+;Y‚¬ 3ZŠµÈ¼•a3 #Fr™®¦…Y1 !@k˜¼É½šk? (M~¯ÎÒºb<#"@l&L®Èžj:1ZŠ®¸¤yJ$,T…±Ì˰‚Q*"ExªÊͱƒR+  1^‘  FxªÇÅ£p??m¼¾ o? à Bs¥ÈÒ¿•b5 Cu¨ÈÉ«zH" +W‹  Cv¨ÇƦsA &K}­ÇÁi8Ã5c˜ÂÔÉ£p? Cu§ÇȨvD )T‰  Bu§ÇƦtB",U‰·ÎÜf6Ã,WŒºÓέzG$!Cu§ÇǧuB (R‡  Bu§ÇǧtC#0[‘¾ÓÆžg6Ä&Nƒ´Ñв€L'!Cu§ÇǧuB (R‡  Bu§ÇǧtC#2^•ÂÖÊ¢l:Ä "H|¯Îг‚N("Cu§ÇǧuB (R‡  Bu§ÇǧuC#1^”Â×ͨs@ Ä Ex«Ìα€L'!Cu§ÇǧuB (R‡  Bu§ÇǧuC#/Y¾×Ѱ}I" à DwªÉʬzH$!Cu§ÇǧuB (R‡  Bu§ÇǧuC"*R‡·ÔÔ¸ˆS)à FyªÇÄ¢p@ Cu§ÇǧuB (R‡  Bu§ÇǧuC!$Hz¬ÎÖÁ•a3à $K~¬Ã»–c6 Bu§ÇǧuB (R‡  Bu§ÇǧuB 43:H\p|yfJ-  1X‡²Ë˰†X3 "@kš*'@cŠ­ÁÁ­Šb@& &@]x‹‘Š{j[QOS\eki[E- "=b‹®Â­Šc@'/Nuœ3!/Gd‚›¨¨š‚dG. "7Odsywpha^]]\WK:(  (Cc‚œ©©›‚dG/#7Sr0!-@Uhw~~vhU@-+=94.& *7CJNNJC:.!%2>G "%&&%"    á"%&&%"  $ ø ð ù ó  þüþþ?¤¤¤ þ üú  øú í  ù- ë &-13321/,)! ùU>' ÷)8BGHHõJKNNI<) á‚eE( 1FUZWRNMRZeljX< €Ä©Œf?  0LdmgXI@?GVj{~kI'À«„W/&Fh}|hL6)'0B\upN*ɾœm> 4[€„d@%+EaqhK)ÇÈ­~K$ ?k‘žf=  /I[XB%ÁÌ·ŠU* !Etœª™sI( 3CE5 ¼Ì½’\. EtŸ´ªŠc@'".0& á¹ÍÀ–`0 >lš·º¦†eH1!á·ÌÁ—a12\НÀ½ªsXA.!â¶ÌÁ˜b2%Gr›¸Äµ ‡lS=+ á¶ÌÁ˜b2 0S{ž¸ÅÈÀ°šfL5" €̶ÌÁ˜b2 5Ux˜±ÂÊȽ«“x[?' ¶ÌÁ™b24PnŒ¦ºÆÊŸ¢†eD(¶ÌÁ™b2 .D^z•¬½ÈÉÀ¬Œf@"¶ÌÁ™b2 %7Mg›²ÃÊĬ‡[3¶ÌÁ™b2 )-$$,=Xuˆ‡pM+ºÆ¾¤}U4$@b|„yeQB;;BPbquiP3 ¤¬§”xX;$3Mcli_TLHINV^`YH2|}sbL5""3AHIGDCCEHJJD9*âMOMH@4&"&()+-/121.' &æ$!   è  þ)p8 ,d Backgroundÿ     XÓ,dXóYŸY«Y·,dY'Y3Y?YKYWYcYoY{Y‡Y“ÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ0ÿ0ÿ0ÿ–2K% commons-discovery-0.5/src/conf/0000755000175000017500000000000011643422202016442 5ustar drazzibdrazzibcommons-discovery-0.5/src/conf/MANIFEST.MF0000644000175000017500000000042410240363425020077 0ustar drazzibdrazzibManifest-Version: 1.0 Package: @package@ Extension-Name: @name@ Specification-Title: @title@ Specification-Vendor: The Apache Software Foundation Implementation-Title: @package@ Implementation-Vendor: The Apache Software Foundation Implementation-Version: @version@ commons-discovery-0.5/src/conf/README.txt0000644000175000017500000000037110240363462020145 0ustar drazzibdrazzibWhen MAVEN is used to build this product (as is recommended), the contents of the MANIFEST.MF file in this directory is ignored; maven builds its own version. This file is only relevant when building this project using ant or some other build tool. commons-discovery-0.5/src/test/0000755000175000017500000000000011643422200016472 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/META-INF/0000755000175000017500000000000011643422200017632 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/META-INF/services/0000755000175000017500000000000011643422200021455 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/META-INF/services/org.apache.commons.logging.Log0000644000175000017500000000201511547711765027250 0ustar drazzibdrazzib# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # $Id: org.apache.commons.logging.Log 1090481 2011-04-08 23:02:13Z simonetripodi $ org.apache.commons.logging.impl.Jdk14Logger org.apache.commons.logging.impl.LogKitLogger org.apache.commons.logging.impl.FooBarLogger org.apache.commons.logging.impl.NoOpLog commons-discovery-0.5/src/test/META-INF/services/org.apache.commons.discovery.test.TestInterface30000644000175000017500000000165311547566516032722 0ustar drazzibdrazzib# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # $Id: org.apache.commons.discovery.test.TestInterface2 1088285 2011-04-03 13:24:46Z simonetripodi $ org.apache.commons.discovery.test.TestImpl3$InnerTestImpl commons-discovery-0.5/src/test/META-INF/services/org.apache.commons.discovery.test.TestInterface20000644000175000017500000000173111546072436032706 0ustar drazzibdrazzib# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # $Id: org.apache.commons.discovery.test.TestInterface2 1088285 2011-04-03 13:24:46Z simonetripodi $ # comment org.apache.commons.discovery.test.TestImpl2_1 # EOL comment # comments & blank lines # commons-discovery-0.5/src/test/org/0000755000175000017500000000000011643422200017261 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/org/apache/0000755000175000017500000000000011643422200020502 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/org/apache/commons/0000755000175000017500000000000011643422200022155 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/org/apache/commons/discovery/0000755000175000017500000000000011643422200024164 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/org/apache/commons/discovery/test/0000755000175000017500000000000011643422200025143 5ustar drazzibdrazzibcommons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestImpl1_2.java0000644000175000017500000000176311546556367030110 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; /** * @version $Revision: 1088931 $ */ public class TestImpl1_2 implements TestInterface1 { public TestImpl1_2() { } public void method() { } } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestInterface3.java0000644000175000017500000000161711547566516030664 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; public interface TestInterface3 { public void method(); } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestImpl3.java0000644000175000017500000000177711547566516027674 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; public final class TestImpl3 { public static class InnerTestImpl implements TestInterface3 { public void method() { // do nothing } } } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestInterface2.java0000644000175000017500000000167011547565546030664 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; /** * @version $Revision: 1090198 $ */ public interface TestInterface2 { public void method(); } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestImpl1_1.java0000644000175000017500000000176311546556367030107 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; /** * @version $Revision: 1088931 $ */ public class TestImpl1_1 implements TestInterface1 { public TestImpl1_1() { } public void method() { } } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestInterface1.java0000644000175000017500000000167011547565546030663 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; /** * @version $Revision: 1090198 $ */ public interface TestInterface1 { public void method(); } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestInterface.properties0000644000175000017500000000167011545720757032050 0ustar drazzibdrazzib# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # $Id: TestInterface.properties 1088164 2011-04-02 22:23:43Z simonetripodi $ org.apache.commons.discovery.test.TestInterface1=org.apache.commons.discovery.test.TestImpl1_1 commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestImpl2_2.java0000644000175000017500000000176311546556367030111 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; /** * @version $Revision: 1088931 $ */ public class TestImpl2_2 implements TestInterface2 { public TestImpl2_2() { } public void method() { } } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestAll.java0000644000175000017500000002675011550164115027375 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; import static org.apache.commons.discovery.tools.SPInterface.newSPInterface; import static org.apache.commons.discovery.tools.Service.providers; import java.net.URL; import java.util.Enumeration; import java.util.Properties; import org.apache.commons.discovery.Resource; import org.apache.commons.discovery.ResourceClass; import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.ResourceIterator; import org.apache.commons.discovery.jdk.JDKHooks; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.discovery.resource.DiscoverResources; import org.apache.commons.discovery.resource.classes.DiscoverClasses; import org.apache.commons.discovery.tools.DefaultClassHolder; import org.apache.commons.discovery.tools.DiscoverClass; import org.apache.commons.discovery.tools.DiscoverSingleton; import org.apache.commons.discovery.tools.ManagedProperties; import org.apache.commons.discovery.tools.PropertiesHolder; import org.apache.commons.discovery.tools.SPInterface; import org.apache.commons.logging.Log; import org.junit.Test; /** * @version $Revision: 1090705 $ */ public class TestAll { @Test public void findDefaultImpl_1() { TestInterface1 ti = null; try { ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName()); assertTrue(ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(), ti.getClass().getName().equals(TestImpl1_1.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void findDefaultImpl_2() { TestInterface1 ti = null; try { ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName()); assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(), ti.getClass().getName().equals(TestImpl1_2.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void cacheAssertions() { TestInterface1 ti = null; try { ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName()); assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(), ti.getClass().getName().equals(TestImpl1_1.class.getName())); // no release, should get cached value.. ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName()); // factory should be cached assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(), ti.getClass().getName().equals(TestImpl1_1.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void releaseAssertions() { TestInterface1 ti = null; try { ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_1.class.getName()); assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(), ti.getClass().getName().equals(TestImpl1_1.class.getName())); DiscoverSingleton.release(); ti = DiscoverSingleton.find(TestInterface1.class, TestImpl1_2.class.getName()); // factory should be cached assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(), ti.getClass().getName().equals(TestImpl1_2.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void findPropertyImpl_1() { TestInterface1 ti = null; try { Properties props = new Properties(); props.setProperty(TestInterface1.class.getName(), TestImpl1_2.class.getName()); ti = DiscoverSingleton.find(TestInterface1.class, props); assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(), ti.getClass().getName().equals(TestImpl1_2.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void myFactoryManagedProperty() { TestInterface1 ti = null; try { ManagedProperties.setProperty(TestInterface1.class.getName(), TestImpl1_2.class.getName()); ti = DiscoverSingleton.find(TestInterface1.class); assertTrue(ti.getClass().getName() + "!=" + TestImpl1_2.class.getName(), ti.getClass().getName().equals(TestImpl1_2.class.getName())); } finally { DiscoverSingleton.release(); /* * Cleanup, don't want to affect next test.. */ ManagedProperties.setProperty(TestInterface1.class.getName(), null); } } @Test public void findPropFileDefault() { TestInterface1 ti = null; try { ti = DiscoverSingleton.find(null, new SPInterface(TestInterface1.class), new PropertiesHolder("TestInterface.properties"), new DefaultClassHolder(TestImpl1_2.class.getName())); assertTrue(ti.getClass().getName() + "!=" + TestImpl1_1.class.getName(), ti.getClass().getName().equals(TestImpl1_1.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void findServiceFileDefault() { TestInterface2 ti = null; try { ti = DiscoverSingleton.find(null, new SPInterface(TestInterface2.class), null, new DefaultClassHolder(TestImpl2_2.class.getName())); assertTrue(ti.getClass().getName() + "!=" + TestImpl2_1.class.getName(), ti.getClass().getName().equals(TestImpl2_1.class.getName())); } finally { DiscoverSingleton.release(); } } @Test public void lowLevelFind() { ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false); String name = "org.apache.commons.discovery.test.TestImpl2_1"; DiscoverClasses discovery = new DiscoverClasses(loaders); ResourceClassIterator iter = discovery.findResourceClasses(name); while (iter.hasNext()) { ResourceClass resource = iter.nextResourceClass(); try { Class implClass = resource.loadClass(); if ( implClass != null ) { assertEquals("org.apache.commons.discovery.test.TestImpl2_1", implClass.getName()); return; } } catch (Exception e) { fail("Could not load service: " + resource ); } } fail("failed to load class resource: " + name); } @Test public void findResources() { ClassLoaders loaders = new ClassLoaders(); /* * To many class loaders when searching for multiple * resources means that we can find the same (same URL) * resource for each loader... * let's keep this to a minimum. */ ClassLoader cl = getClass().getClassLoader(); if (cl != null) { loaders.put(getClass().getClassLoader(), true); } else { loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), true); } String name = "testResource"; String partialPaths[] = { "/test-classes/", "/testAlt1/", "/testAlt2/" }; int expected = partialPaths.length; DiscoverResources discovery = new DiscoverResources(loaders); ResourceIterator iter = discovery.findResources(name); int count = 0; while (iter.hasNext()) { Resource resource = iter.nextResource(); URL url = resource.getResource(); if (url != null) { if (url.getFile().indexOf(partialPaths[count]) == -1) { fail(url + " does not contain " + partialPaths[count]); } count++; } } if (count != expected) { fail("located " + count + " resources, failed to locate all " + expected + " resources: " + name); } } @Test public void findViaDiscoverClass() { ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false); DiscoverClass discover = new DiscoverClass(loaders); Class implClass = discover.find(TestInterface2.class); assertTrue("Failed to find an implementation class", implClass != null); assertEquals("org.apache.commons.discovery.test.TestImpl2_1", implClass.getName()); } @Test public void findInnerImplViaDiscoverClass() { ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface3.class, getClass(), false); DiscoverClass discover = new DiscoverClass(loaders); Class implClass = discover.find(TestInterface3.class); assertTrue("Failed to find an implementation class", implClass != null); assertEquals("org.apache.commons.discovery.test.TestImpl3$InnerTestImpl", implClass.getName()); } @Test public void instantiateViaDiscoverClass() throws Exception { ClassLoaders loaders = ClassLoaders.getAppLoaders(TestInterface2.class, getClass(), false); DiscoverClass discoverClass = new DiscoverClass(loaders); TestInterface2 serviceImpl = discoverClass.newInstance(TestInterface2.class); assertNotNull(serviceImpl); assertEquals(TestImpl2_1.class, serviceImpl.getClass()); } @Test public void findImplementationsViaService() { final int expectedLogImplementations = 2; int actualLogImplementations = 0; Enumeration logImplementations = providers(newSPInterface(Log.class, new Class[]{ String.class }, new Object[]{ getClass().getName() }), null); while (logImplementations.hasMoreElements()) { Log log = logImplementations.nextElement(); assertNotNull(log); actualLogImplementations++; } assertEquals(expectedLogImplementations, actualLogImplementations); } } commons-discovery-0.5/src/test/org/apache/commons/discovery/test/TestImpl2_1.java0000644000175000017500000000176311546556367030110 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.test; /** * @version $Revision: 1088931 $ */ public class TestImpl2_1 implements TestInterface2 { public TestImpl2_1() { } public void method() { } } commons-discovery-0.5/src/test/testResource0000644000175000017500000000005407576207474021133 0ustar drazzibdrazzibthis is a resource for the test(s) to find..commons-discovery-0.5/src/testAlt2/0000755000175000017500000000000011643422201017216 5ustar drazzibdrazzibcommons-discovery-0.5/src/testAlt2/testResource0000644000175000017500000000005407576207474021656 0ustar drazzibdrazzibthis is a resource for the test(s) to find..commons-discovery-0.5/src/testAlt1/0000755000175000017500000000000011643422201017215 5ustar drazzibdrazzibcommons-discovery-0.5/src/testAlt1/testResource0000644000175000017500000000005407576207474021655 0ustar drazzibdrazzibthis is a resource for the test(s) to find..commons-discovery-0.5/src/site/0000755000175000017500000000000011643422201016460 5ustar drazzibdrazzibcommons-discovery-0.5/src/site/resources/0000755000175000017500000000000011643422201020472 5ustar drazzibdrazzibcommons-discovery-0.5/src/site/resources/images/0000755000175000017500000000000011643422201021737 5ustar drazzibdrazzibcommons-discovery-0.5/src/site/resources/images/logo.png0000644000175000017500000003225210006021306023402 0ustar drazzibdrazzib‰PNG  IHDR,d³cš—bKGDÿÿÿ ½§“ pHYs  ÒÝ~ütIMEÔ1Û͑РIDATxœí}y\TW–ÿ}UE±èüá¤*íi“ž¤ÝP–‚Øæ3IGiqA6—6ÝIƒŠˆ™É¤;=“i[‰ˆ‰q‘%!ÒD£öLGE$i'i¡ ¨ªȾTÕ{¿?ΧÎî«*pIûk|ç>EÕ}ç{îùÞsî½çÞ+H’ÄRH¡ûGªû-€B =褀P!…î3) TH¡ûL Rè>“B…ºÏ¤€P!…î3) TH¡ûL Rè>“B…ºÏ¤€P!…î3) TH¡ûL Rè>“B…ºÏ¤¹{Ü> Aî«»ä6ì+†e~[…¿¾?ÝÞ[ÅÞ½¢¾'UÿMpg[™*++ËËË+++áq½^o0"""t:hþ–UcccQQJi0€2–›Éd*((ˆŒŒŒˆˆà^QQQÒêõú„„Ž9å\PPpîÜ¹ÆÆF¨—çÂ.«SXX¸mÛ6ú¥ ”mDDDBB‚;]™L¦òòrT¹ ”¾”9›)!!{é°Ü***ŠŠŠ¨*€aa!Ú@BBÇyX¶ð¸ÑhDhB¯¾úê¶mÛFÞôÛ$Ý&mß¾]¯×»ãwíÚµ›Íæp8DQEÑ«ŒŒ ¬t:Ýúõë¯_¿>88h·Û=sËÏÏOLL„óòòm6›Ýn/++‹ŒŒ”37 W¯^æÀÙ<. sÆŒŒ |—ÍfCܱMIIéï狀jllLKKs© yamTQQá²Ö´™þô§?¡„î[^^ž––†Âƒbëëë7lØà²Érssûûûi“¹”«©×ëããããããÞŒ±øøxèCá]ž%t ¬¨¨ÀöHMMýŸÿùŸžžž®®®+W®,]º”6FvvvOOO¿;‹)((@Vëׯ§¬¶lÙD¹:t¨··WnF£qûöíˆ=¤œœœîîîžžž””†ÖÑÑÑÝÝÝßßöìYÝc,(( S1***ÒÒÒäßÝÝÝÝÝýí·ß¢m¹¤Í›7wvvBí8ç)§ääd, v)o#£ÑˆÂDDDäææööövwwwvvøzƒÁðöÛo[NKŒ±‹/¶¶¶ÆÆÆ2§ó?|øpvvö–,Yâ²pWWW¿Ü.i/ßÝÝÝÑÑÑÖÖvóæMTìý×Q†AAAþóŸ¹Î%11Ñ¥b÷ïß¿ÿ~xjíÚµ‡ÊÎÎNNNæh6›ÛÚÚ ½8b§ù§?ý ­è&!ì‚­VëÍ›7ÛÛÛ»»»å|F„ˆ@N×ÓÓsëÖ­›7oZ,––––f'½ùæ›´%š››[[[9 "+ÆXNNN{{»Õj¥|€L&ÓÂ… )Ãŋ߼y³³³“š‹Ãá°Ùlééé´dtt4clöìÙ¥¥¥7oÞ+4›Í&“©¢¢‚r×®]Œ±˜˜˜+W®@wpóæÍ–––ÆÆÆòòò€€Z¸¾¾Þl6ߺu«¯¯û‡Ã188ÈyŸ?ÞÛÛ#CƘJ¥R«Õjµ:00pß¾}øTww÷¤I“~øaAT*•J¥² óÍ7a Å±‚ .ÌËËëîî†òß~ûíøÃGyD u Ù²e ¾ú/ùËüùó÷ïß IàÄápØív??¿®®®K—.¡Ç_°`ÁÞ½{ÇŽ ep0ãëë+IÒÙ³g±°Á`ð÷÷WbŒÁ+üüüŠ‹‹© Ï?ÿüرcc¢([‡Ã1sæÌÂÂB¬WMMÍ_þò—]»v­\¹»,ÔZ­ÖjµÞÞÞÞÞÞÿðÿÀ 9{ì±ÞÞ^t\’$mܸ}å•Wúúú`ä Š"4póq;ýîw¿ëíí¥ƒ æjUcÆŒ›7o†i í€!j4///.Ð1cÆÖ­[AN´Z†QcF£±¿¿Ÿºbø,’–LMM}â‰'`¸…Õ¶^^^`ñH7nü§ú§¾¾>(–‡º Á’f³Q­$IÛ·oGÆÄÄŒ7š ˜*ÖÛÛ{Ó¦M4†<~üxYYC V«ÅøÃ~õÕWçÏŸÿßÿýߨ¨(Œj  ¨¡„„„p6‡Ü ö@Óáæ]Oœ8A»XŒµ8±±ã¤Ö××Ì…+Œ!(s"ÌÊsli¸ˆ½†¦\aÆZxjµZ®$ÂF¨x(ŒƒÒÂÂBì(cÓ¦Mƒi¬U,èÖÛÛ;>>ž²­­­mhhÀ00&¯† 'h•kˆÀÒè±i‡²yóæ€Ú¡'…7‚§OŸ†žÝËË p8Š¡è „F£}Whh(tlÐuy9 GúÁ€ ù!šá£>BÎþþþ€"æŒg(+høž›£»|ùò€“„.m¾G ³èÔNr­§uª‡Ç™úvŽº“»v*ƒ;Ä¢ ´¤¼°è$Ád2Ñ_éh̓b5 7â­­­å]—•B­¢w…oä ‘ë VŒh™K—.ÅÆÆFEEݸqƒŽ´1>BºlµÑAžêvîÜ9ü,Ivt   ÇŒ3vìØ±cÇB@UUUE9C7 16!gÊÈ[nii±Ùl8Ôt9^§6ÞUp•¢Å™&’\”Ü%å0â$9žrF^X.Cee%ýG¡T·.•Ã-Ç›Íf ©Ÿw©+¹bÝ ‰„ß§§§ÇÄÄp…/\¸0mÚ´ù—¹~ýº| ø@{BÌ9dÎ0Œ sâTà ÖÑÊcìð<4$ðç:l0•y¨‚ £‘”ôÀ9{ÃNÖ¡½Ë“v#€‘Z.޲<è¾á¦|àY.ØI¥7½›»Çsrr^yåù¯»wïþÙÏ~–™™‰~—Ýèè#· äÚàÒ¥KtÂÞ”Ò1!Çü‹/¾ ü= ÐåO¸ôçÁÊÅ£?yþfØŸFˆÃï›\ €ºI§#gˆŠ¶ƒ»3 W›7oþä“O&NœÈýÚÜÜü›ßüæÑG­¯¯—ÎF}ööÈ÷šÍf6.‹!l†íÃî¸ýýý¹8ç¯ †û޽ae¸cÅ2FÞ¡d‰öÑ‘‘‘åå寽öš¼XSSÓ¼yóòóóq…ãûæÿºñîÉ“'iÞ‡’òPžˆxúôiwÃŽ÷Í´iÓØ÷l+[Ä%—¡bé¨ÕC¼€Ä)öûÃ!Ìòí¯~õ«?þñ¿üå/¹bÍÍÍo¼ñƵk×`é¢ÓÑÚÜž@È-%9rçF’ÄhÜüÊ×_Mg˜ûþ›ÚÊŒ3ØíŒßò XwIE.鯦[Ap}̘1S¦Lùío{êÔ©§Ÿ~škiiyÿý÷¹‚Q‰CO œ4iý·®®®¶¶ÆcÃ"§°°pÙ²e´Oå ]WW‡¬<› M€ŒDÎPp(rQ†Åb±X,"!wRÅΜ9s„ ß7—/_ž™™ ü¹‰ôýèG;wî|çwhùãÇc¢â(ŽK=Ð`0p½ì믿ÞÔÔD³œ]>XYY¹lÙ²£GRSà@øÕW_!=trÜ"ØÓO?-É÷Ñ=s=B çš 4ïyîŠ Õíüùó9Å~Oº­¬¬D‘h\:vìØ¿û»¿‹‹‹{þùç±°Ùl†cšÔ:úœá0cBniÕb±¤§§766bþ¤¼‘‘‘aaa4Á*<<œ[l8}ú4Nˆ»›§é /¼ðlbÀ•t„Œ1AÖ®]K¿9sæ dÕxXÈ1™L¸ÀðÌ3Ï$[ÀåâûÝ“$I………4˜‚5-À!¸Ä¤¤$úÍAug$ëä „‚ ¬_¿žKn:uêÔŠ+*++)±‹Ú¾}{dd¤ÑhÌÍÍ…•_šœ““CYåååµ´´`†¡Ë~3Na& Ó¦`ùQÁ!4ÝÂb±X>Ì­¦ºS,c v-RźLë¹W”™™‰é’3k 3ì~øa,9}útšƒ:*Ý óBn½õÖ[ÜOf³9>>>88ø_ÿõ_óóóóóó ÒÒÒ&Ož ›•rss'L˜@·PHÎó ²²²(«×^{ ½¥¼ŸÃ=AAAÅÅŘHYã÷¤Ãþ›nW¨¾J¥:tèÝq²cÇŽ¦¦&ì9g'ƒÀç}ûöÁ” 8¥{•¡â0;wîlhh Î ›U«Õ¶¶¶bI’¹ ¼ÑGÃxB•J•pàÀù¯ÍÍÍ{öìyöÙgW­ZµråÊ;v`:´páBÜu†ë­ê$$$À @uuu6l ¹ Øm¤u:ݧŸ~:~üxI’pÿ¤@oÍ™G\Ñ  À° Y,–‘Œ¯†%®0Ê0²X,Ü7 ÛÉ“'þùç‡Ï>û¬Ñh¤ÁÑhÄ-ZYYY ,À¤|Ð-$Ó ‚ÐÔÔ4rÁh’#cÌjµâg&“é׿þ5ä©Ò>\1œuÀ‹ŽŽ~î¹ç<'T&ä€.*>>žÛ_ë’‚‚‚>üðè¨(Üò' Ms-'$$”””àÐ/¾øbîܹ»víÂÞ‚‚‚9sæ,_¾œ1f0>ÿüó &ˆdW€3Né,cìÔ©S`òU2I’¸Â‹åôéÓø+G™™™´p]]œ3|àØ9ryrÈ Ÿ>}àÍÅ’l¯ s.²¡+¥ÐL“'OþôÓO,X€U{òÉ'ÿã?þ£¢¢ú¸òòò7Nš4Éh4êtºìììèèhÀ'„Ø» ‚ðî»ïްRÜv*“ …ÅaIIÉ¢E‹`PCw'¿úê«ðÒ˜˜˜Ý»wc²øèÿsî¨äÜA×××wõêÕW^yφà襗^zùå—áD 6tËMEn==={öì9xð žÝÀœ4kÖ,Üð ¶ؼ½½;ÖÜÜ\TTÄÃó÷÷Ÿ>}úâÅ‹úÓŸ>òÈ#ÞÞÞÕÕÕ•••. 3Æž~úéE‹M™2å‰'žðñññPØßßÞ¼yaaa?úÑ~øášššóçÏq&È›>}zpp°Á`X¾|¹ŸŸŸ——Wqqñ¹sçäö lçÏŸ>wî܇~X«Õz(<}úô¨¨¨É“'Ï;÷‘Gw’$ÙíöþþþÞÞÞ²²²Í›7×ÖÖºT¬N§[·n]RRîf¶ÛíbøùùùøøÔÔÔTUUah#—+eµZ«ªªŠŠŠ¸íT(ç‚ âããüãûøøh4š+V˜L¦‰':ŽÒÒRÆX```XXÝì¦ÓéÖ¬YóòË/ÃIp‡ÃËË ¦m|||p{¡ËªýÒð öõõõöö^¿~½ªªêäÉ“àåüýýgΜ…}ö^¸•ÃæÜ“ Íë°ÕÕÕµµµ—/_W©V«ccc C`` L-@@%Š¢J¥‚Þxþâ¿@!Eç6?Üž ½@rròܹs½½½wïÞÉ0À Ûགྷ!55 Cp……qn9 †9sæìÝ»ëEeÀôtF“••åçç§ÕjŸyæS¥¹ÂÉÉÉO<ñ„V«Å$àLç™±ðÚµkç΋ATj``ÛØØXSSsòäIL!4 ƒ!,, [*±(ìÐÕjµ;wrùꬬ,__ßÚÚÚ÷Þ{Ú ’cHJJš;w.àçܹs'Nüû¿ÿ{8Tª¦¦ÆjµÖÕÕµ´´À®Ž°°°¥K—Úívèym6c 7ÇAM¿¿£ûEßÀæ8ÄujîˆÜÃÊ!{/Ê MOûÁ-j hâ„nÏŤphx@uOOS £GXöóó1€'À \1EQ­Vûøø@aìnñÛ½½½´0ØpIDQÄ~ —Á²AÜMÓ `dÀ 3Æ 0²%`aÁ”3Š8Ä“‚Eçn}:ã€õâä$nÞƒ–Å‚œðjWØi¥ úб¢S©TÞÞÞ UØÑ&‚Ãá€ê 2élsfçãÜ©Z­F[­{š†¿‹Bpn]‡mæ*çžw:ó)8s1¥h¡Š£Üð)ºŒ]/ˆƒê]NŠÂÛ1ì‰1†Î‘-°9D Q ]8ˆá¡0pÆÂèy Â™³+ñ(6€T*Md÷Baìã­ÊyÌ·¤†œ¢t}ºB(œqO*–¶…ÊyÆP‚2C—rÒWƒœ  ´€4Nö`Kä°)cà„±Ö('6¥ŠlíÅÃÂ]C‘ƒYðÜÞv\çÅ“/Ü­ã dCpã–(hòçcݵÎÙ€•Käx5ê„™§…^¬§Èå[éia­VK9s $*çñ0jµZtî~¦Ž’¼0Z'WAÔǘsœ9Åzyyq¹Mt²Q®XÊòáäÄJqr"º wƒÇ)~€ ŒF£A©85+ÕÐsF_ŠtÂ`ïHÓ\èü2mT„Ÿ»® '÷F§äˆ9ÛŒ>"Q'Ô„0ÂDÂÂT~ÎÓÊ #gt‰Œ„ÙèÁ0†‚”--Œ2 ‰{(¬JÔL1’Iz *–ê–Cˆ¼¡¹´ù«ÙÐQ®­baêÀ©=üŸ]mpí>úèöne€ArΧ‹$}‡äYk™jÇ&A[aC}&µÊ›S”å…Pƒ£FËÑ…³¤jèV^Xp.‘£œÒPâd@¶ðåm LíÕ]aEŒôqœn™,ÐÀ§¨nñA9Zä¯æÊ»Ô*!Cièþˉ7Zát'W£Q}ÉMs$ð“sc®r,†e(—D.º‹|$…ñ¯KC‘–WÄsî¡ÀžUäîYîît{[ M›Ï¥¢Ü™åŒÝ„‡J>ºÃû \bænH.Ìy[ —h¹'…GH·Ë“áÈ™»$—LF¢Û‘ëê¶´:ì‹ì!ݺ-2™L™™™F£1--Íå•i”å)„¤€ðžÜ\[XX˜ššš˜˜H#+øùbðoYYàP"'ùúÁB.iÔNûþÕ¨°°2õz}ZZZEEÒÀyÅ‚‚š¶}ûvœdö°áH¡F´N¨;züñÇM&—c Ëât*R¥Rq›ßƒ‚‚ Á‘ùC漃Eñ‡)žð®¨¼¼¼±±±±±‘žf IyH°ÔЇÁèt:ÈŸÆ{5ðâÅ>€¤x»%I’‚‚‚ úCH¹äòKÔjõáÇSRR—,Yb³Ùèí¨"Ùuyë¢Ð}!„÷†¨ï²ÙlÁÌœwÈᯡ¡¡³gφŒ?ø e˜3m òK•pô"„wKòèöõA:¤}3’´Içl0ÿ[åL‰F† R@xˆ!Œ m6› °Q€æÓb1À¤^YY S¾’$EFFÂKåãUø cõñ³N§Ã·Cᦦ&z~ÆW¸”jƒ Ʀ%ÉkA5åA-À„›£ˆˆx9ÓCºF"öˆHn+ ¹£íÛ·s·Û2ÆRSS¯_¿N¯FÊÌ̼xñbeeeyyùùóç¿úê«7nX­Ö+W®lݺ²Õââ⺻»;;;;;;»ººàH<0##Cþ¢ˆˆˆ£G&$$=z·ùѽŽ(gEEEdd¤¼­Ξ=‹ïr›Béãî:—ÔÔTà  ¼¼|Ø—âFð††î6l€ãö8ÁDQt©v½^¿mÛ6Ž-§Š‚‚xK~~>üš‘‘A™”•••••¹ìžÞyçúúzŽ~~>•<22òÆôì\ys K GDF£ì@¯×çççï¾¾.0Ñét4!;33óÂ… ÂÜÜÜ7Þx#44”¶q\\\OOO·“èÝC°¦¯×ë322¾»ÛÜÜ\8B¦èB¿Ñh$DFF‚åÙíöúúzzH|||?å ÞÞÐÐ5ÍËË£–º~ýzä@@á‘ÒÓÓ{ á#`¯ùùùP,//Ï¢‚åççëõzÈ„c¦·mÛF%ÑétW¯^¥ÂØíö²²² 6PÜ=zÔf³ÉïçUôõõ¥§§Óï·nÝJņ#<ñtF¬fBB¬÷â¡>œ>Gh] ‡' œp¨ëôÍ7ßpÑÈöíÛ«««ËËËËÊʪªª¢¢¢¢££—,YÂó„p’Ò†  Àå‹rrrº»»á *<âÕn·ƒÉ2ƽ€°ÞÞ^*äºu뺺ºü`: ØÑ444 yÁÛ{zzbcc©õóÍ7 ro@­?66öÖ­[íííííí·nÝêììÄšÚl¶£G2Æ"""@Bì’  sª×ëÁÕPµÓ¸C§Ó]¹r«c0ä`ËÍ͘ÅÅÅQ=ÄÆÆvvvvtttttÐë–.]ÚÞÞÞÖÖ†bwwwã½4XÇ/¿ü’JŽÚà®u–CÔÒÃB·nݺuëÖÉ“'i“oÛ¶­ªªª¬¬ììÙ³UUUuuuׯ_·X,kÖ¬¡ÍßÞÞÞÚÚÚÚÚÚÖÖÖÑÑÍ ¿B 'á‹ÚÛÛ7oÞÌ‹‰‰‘›u}}=> & öÚÓÓÓÕÕÕÙÙIß΃W‡ÞÞÞk×®!xÊÊʸjvtt€111È!,,¬­­Ê®€^od±XZZZš››Ífówß}×ÞÞ5LMMeŒ¥§§÷ôô@ÛÚÚ€ç™3g€C}}=dÿqj§˜IJJºyó&ª椕]·n]PPÐ×_ÝÖÖVWW‡÷v|øá‡V«.“ûÝï~GÅ™›››[ZZ¬Vk[[(j``àìÙ³ÐwôõõuwwwttÐæ€2·…C%IjZ¶l Üñ¾1ì•1 ¦Ñ&w¬ |)IW²F1Œ±Ûí8è—Èž4 õå—_ ’$ _ÑàܹsáÙwÞyŸ¥e-ZDëU^^ާ*þâ¿€jFDD„††:ȉ¯PYø°ÿ~´þóçÏ¿þúëP z‘Áš5kÐÛ455ÇÆ  ´¨¨H§Ó­]»Öá<·_Ç®ÆÅÅÁIÁ8èB‘/^ŒuÙ³gòL˜0zË;w–––Ž7®··wܸqÅÅÅûöí+))™?~¿“è•lMMM»vír‹Š¢ç²ÇÅÅQ=ËёۘBOTYY ±¨^¯ •Çã'Nħ¤¡QÂ2¢(‚§BÓÁTRÆØG}„á(¼nõêþ廡+IDATÕ’óXtà½÷Þƒ9Àõë×È{ »Ý>kÖ,4Ü… N:í¯¢¢o’X»v-};­^½k±oß¾ëׯzÿÏÒ¥K±Ì|€5¥—œ™L¦¸¸8z¢¼z÷îÝp ÆÒ¥Kñü(ÚØíöàà`ÚRÅÅÅ©¶_yå@ âêg?ûÙO~ò…ÂS/½ô>RZZJOÙ¥}œK;e”8r*Kž(-- >„‡‡sê¦)×Üâõ~î8ƒ'´;Ï·EQ¼Ÿƒ1öË_þrÿþýãÇçÞ5{öl‰<ñ¸ÒAÎö–Èå¾}û.\(ŠbTT”ÍySˆ(Šø8c,$$ÄæLmÅzPÕ¢E‹Þ|óM,_RRòâ‹/BBÞc‘œœüþûïCšš£Ñ8~üxHÍÃEQ¸mݺu4‰ôPRRÏšL¦>úH"‡¯b_ÖÜÜLõùé§Ÿ>õÔSjµkM ›1c Õ°:Ü©S°xûÜsÏ}øá‡ðå¥K—.\¸0mÚ42EQüøãcqqqÀÐî<› ½ d䤀Ð-áÂcÌ`0ÐΘš¦|ëÃHN4E¸IÎ…{F^UUÅ«ªªZ°`ÁK/½ôÜsÏIÎËÃA˜={vHHÅyuu5^Ÿ´dÉô'B(*¢éÀµ@x§Ü¨âNráÂ(ñâÅU«VÙÉ¥.fâĉK–,A,åä䤤¤ÀãpªÑhÃT@¸\ !?¤Ä«©©¡Rá¤(n†”†ž°®Ñhè¤ÈçŸsH¸1^J/Ü=uê”4ôÄÚÝ»w3ÆÖ®]+Õ?޶¶¶Z­Öæææ†††k×®]½zõÚµkõõõ 7nܸvíÚ•+Wjkkßzë-nTÉuyt<é 'Vã@4Ø®«««««sE±¸¸X§Ó………‰„¤¡·ÝnÚ“B·„·I³¡ÆM[;¦J—Ÿ¨ë®k‡’$I!!!¤Vn6›·nݺ|ùò .`x)xÿð‡?P9Ñi %éáè¸Ë‘»ðGƒr ãñêtȇÊAÜ‚rBCCq"Êb±äååaTép8JJJ‚‚‚BCC¹é+.ÇÀC¡åz ±@‰Å°–‹Ã¥Ógé¥)pË··÷äÉ“CBBðÁ3gÎHÎ[qÇž={cK—.¥c~* ÂBQ¡[¢ÙL=ÊÃ<°f„Ü!ÂÌý!NòÉ›˜˜˜Ï>ûŒ[Ü¿téÒ²eËbcc›ššèÛ¹H˜Nظ”oÅûB F2™Lˆ@ÎcPèrU@ð£'„ÐËÀ’”,--mnnþÕ¯~E“K`ãSçÏŸ—Ï=Ò¨³~w[1é—Ô‚*|œ:Ù´iÎË˳Z­¢óŽèï’’’\Jއ…ß®3T@è–hWj2™pVíÀ]Χ@ÎŒqGÔCÊ¿ üÃþðÆoÐIWÆXMMÁ`8vìõr”É'Ÿ|ÂMÓQŸ©v^퀡ÁµôÕÕÕ.9Ñý”Ä¡gæƒ~’““ñæàººº¯¿þ@çÂ… ñ-ÔcS½™L&:qÊÍþcÕÐEc7!G#‡XµóvnoBÐ+EFFÒÒzDQlnn¾páBHHÈ„ ¸¥D úŽn­Q@8"‚.™3MÁÕïlè9óQž"à¹zõêÿþïÿ~õÕWýýýé¯ÉÉÉÇŽ£>©ººÚAŽocCO¡G‚µAßÿøãSÍÍÍÔâ©<È„ÊŒÑ š&xB•JEG†à ÍfóçŸþ /üà?Àe4eN“%%%Ž¡§Ñ±¡±"ªƒÞ oƒâZDE®Ð¤ÏzÒh4”——g±XDQûL$?ÌÕõ°Z fÇÍs ‚ ×ë“““±p^^^^^ÞôéÓ§NÊ™2szB* c,++‹C WƒŒ‹‹ƒÛK}}}ášWÏ=#HŽÔj5ãèÑ£V«õòåËóæÍ£ 4R nݦ( tK\ðÛo¿MA(];¦tg:vì˜Ê9©C§ï´ZmTTÔªU«°¤Ýn‡<©S§ÒUþôôt³Ù,ŸweN8­X±bÛ¶mhsëׯ§2äæærn«)dç0ÆBCCgÍšå.ƒ B»§žzŠ.¢8Ƚ”ðHxx8U»Ùlææ!éd¯V«]½zuPPPbb"mòÐ .É n å- ,]¬\¹æ=xÂa# 9) ôDÔ:kkk>,·NƘ$I˜öÅîú™÷ߟ‹¸pæ€æj=ôÐCÖ<00@óc/¼ðÂåË—éê \XX¸|ùò 6ÐÍááátÕ¶/¸«©ÉdÂÅ›ÿüÏÿDÃå>࿃¦a9dÅŠ8•Ê­ÚÑ´OÆØóÏ?o±X8‹.ë¹çž+..NOO§w­«F|r$†‹WÕj5&µX,þþþ=ö˜Ëõ›;Dz¢””j¬;vìx÷ÝwqG_+W®DçÀËÊÊÂÎÛ·ô@˜ð¥"—„[[[á'ÿ©S§Ú›•V­ZEñi±X^~ùå×_ýĉ¸H]TT4wîÜ+VDDD¤§§SŒ‰¢¸eËÚñ0²¼†HfŒmܸŠeggÃp”:jŽhÍtǪU«pIƒó'øHJJ u†P#GŽp=ÂùóçŸ|òÉ?þ8===""âŽ%ô*•*>>žŽ Ÿzê)Ékç8çNoë¥ Ý’ :nË–-ôË£GÆÄÄddd?~¼¤¤ä7ÞxôÑG«ªªè²¦¦&** 6Âã—’$ar™g2™LÏ<ó šÆ¥>>>ÙÙÙP&--M¥RIä~ÜŒŒ n=ãôéÓ¯½öÚ£>:iÒ¤ñãÇ?ûì³çÎÓét¹¹¹t9,;  ´´WÞ{ï½?þñ’3Í=jAAlõغukLLŒ$[-ÀtŠÃøøxDøüùór]±|–Œ8''‡f,X,–wß}7$$$555))饗^š:uê“O> ¹o\™|Ðn6›G¢yZ‡hW®\)‘Ý-g¦+–¿cü+ ôD‚ ÄÅÅ8p­“1fµZ9²qãÆµk×îÝ»—1vòäI:* NKKûä“O–-[FfŸ|ò –9~ü¸Ë(..~ôÑG?þøc“É$I’J¥úôÓO—.]ÚÒÒÂ{÷Ýw£££qI ˜O˜0!//Ã!G111'Ož?~<Ý …ötìØ± @áÿ÷ß¹s'†µçÎ{æ™gV­Z0^³f8t©š[Íçæ9ÀšgÍš¬šãÂH.zNwòäIªv “'Ož8q¢´´z´ìììììlºFcqq1>uðàA— ñ0¤±ñD‚™3gNœ8»Q–`€•º*W£¹%0ˆ÷®]»¶k×®¬¬,®Ì‹/¾˜””4iÒ¤Õ«W—””üó?ÿóüùóÿñÿ6­J’ÔÖÖöí·ßþùϾ|ù2æ%Mœ8qêÔ©O=õÔôéÓ'MšäççwæÌ™'NÀLFqqñ±cǸ×-Y²dõêÕÓ§OÇÝOÐã$ª$IYYYÙÙÙ\2Zppðoû[ƒÁ _ÈÆþ+[YYyàÀXK ´víÚ””æ<[7ÙívÃÇÇæ'qGXm}}ýc=V\\L•£V«½½½}}}qiÁËË zàß××÷þûïðÁ\‡°pᤤ$½^ë–€¨={öTWWËUÚ~òÉ'ƒƒƒ'OžŠ(Šv»½©©©ººp»Ú*¸AèååÅœ;ŒFãÅ‹a¬5þ|­“ÀMq“8“ÁA«¶¶ÖjµªÕj­V»téR˜úñÎc>`ªPE•Js¹`”˜Ím³ÙÊÊʦN Ûù ûP©T„t‘øãá7nܸxñ"ô8ÁÁÁz½Þ…^[­´´”ÌÀ7â†@I’„øR—s9ÐÛív___ÆØõë×áô›ÍƃîÆÏÏ‘ {g©²•É©T*°\µ›={öÔ©S¡;CaŒ‰¢ _Ðl¢3‘‚1æïï?yòdè5½½½Õjµ(ŠƒÎàgÅæ§³8d.X°@µsÏ!š® 3õ`ô€1N7~üx0;»ÝΜ} ®JãŽòDÌ€ ³fÍbŒÁäTVpŽs$Y¸C1T$±ìR­VÃY2Z­µœ©H †äÜž‚úhåÊ•P222255Õh4¾ú꫌±·ß~›[y¨ÛˆÃ¿Cs7*UˆŽ ùåûkØÐ}º‰!é÷” ‡a4&®0E Ü%¢7  O9œgIˆ$ ›ƒ ­,#óŸ(' Ø8ÒÈ9J2däáÔ¹Ãy¢U˺¸Tj >eÊ—wÂÄÅÅ:tÈAu8o_†DBùøÎHñ„#"®cV©TÔGaô_Ä#ƒFŠa WZØåæKß+9ñŸ#’½¿9. ÙøÀÕ”Éz¹ ît(8£qÎS¹|¾G-AE0¼ä$Q9Ç´ø“ä<Óü9})õÛ:NBN÷ûßÿ~``@$çÖ02wÙÝ) )¡A`c˃~òŸÐ™ÈcK&³EAæ\òtgýÃBHþFye%7‘°¼²#±E—µöAŠ^wÕq'V:#®<|HMM¥'ë1ÆÂÂÂöïß?nܸþþ~ò t¹°å.q¨„£wBœQ¹³f—Ïzü<¿Ô³œìv`s—Ü[ò\—ÂŒDÛ’$ÆÌÌL£Ñ(ŠââÅ‹þóŸÓ,0ŒÇuKXvÒÜ£{]*ô@`LtfŠâMºwCP€ŒqMH5⽋îH Gz ‰ŽQEç¾-Üõ/9À§³ÐòµÐ»$e+“B ýÑ'€r Æ½Z §¤xB…bŒL£¯ƒïUÎMÕãzOÖ$8R@¨ÐƒNèÓ0·Ò˜`Ur*ðxRš%s¯p¨€P!…þ/YzA€Á¡@ä±è½z»B…tÂå{üÒ%r*—{P–(RˆÉ2 q†F yyˆÀ{‹ÃÿáÜûBgžIEND®B`‚commons-discovery-0.5/src/site/site.xml0000644000175000017500000000363711545733764020203 0ustar drazzibdrazzib Commons Discovery /images/logo.png /index.html commons-discovery-0.5/src/site/xdoc/0000755000175000017500000000000011643422202017416 5ustar drazzibdrazzibcommons-discovery-0.5/src/site/xdoc/proposal.xml0000644000175000017500000001046310653172436022016 0ustar drazzibdrazzib Proposal for Service Discovery

The Discovery Component is about discovering, or finding, implementations for pluggable interfaces. It provides facilities intantiating classes in general, and for lifecycle management of singleton (factory) classes.

Fundamentally, Discovery locates classes that implement a given Java interface. The discovery pattern, though not necessarily this package, is used in many projects including JAXP (SaxParserFactory and others) and commons-logging (LogFactory). By extracting this pattern, other projects can (re)use it and take advantage of improvements to the pattern as Discovery evolves.

Discovery improves over previous implementations by establishing facilities for working within managed environments. These allow configuration and property overrides without appealing to the global System properties (which are scoped across an entire JVM).

This is not indended to be a replacement to be used strictly by the user, but rather a replacement to be used directly by projects. Use by the user is also reasonable, but limited due to 'keeping this simple'. In particular, there is no configuration for this discovery service, it relies soley on usage patterns.

Given a java.lang.Class parameter 'package.Class' that represents a fundamental service as either an interface, an abstract class (or even a regular class), find an implementation of that class:

  • Look for system property named 'package.Class', the value of which is the name of an implementation.
  • Look for a 'local' property named 'package.Class'...
  • Attempt JDK 1.3+ style discovery
  • Attempt to load a default implementation
In all cases, verify that the discovered implementation implements 'package.Class'.

The package should :

  • Have an API which should be as simple to use as possible
  • Be based on usage patterns, not specific configuration file
  • Represent proper discovery & class-loading principles
  • Be reasonably portable across JDK levels (1.1.8+?)

Services relies on:

  • Java Development Kit (Version 1.1 or later)
  • [by design] Nothing Else, particularly anything that would be classified as a 'service'.
  • CVS Repository - New directory discovery in the jakarta-commons-sandbox CVS repository.
  • Initial Committers - The list is provided below.
  • Mailing List - Discussions will take place on the general dev@commons.apache.org mailing list. To help list subscribers identify messages of interest, it is suggested that the message subject of messages about this component be prefixed with [discovery].
  • Bugzilla - New component "discovery" under the "Commons" product category, with appropriate version identifiers as needed.
  • Jyve FAQ - New category "discovery" (when available).

The initial committers on the Service Discovery component shall be:

  • Richard A. Sitze
  • Costin Manoloche
  • Craig R. McClanahan
commons-discovery-0.5/src/site/xdoc/adc-guidelines.xml0000644000175000017500000000325310653533705023033 0ustar drazzibdrazzib Architecture/Design/Coding Guidelines for Apache Commons "Discovery" Component
$Id: adc-guidelines.xml 561230 2007-07-31 04:17:09Z rahul $
[Introduction] [Security and doPrivileged()]

Kick-off: set of design/architectural guidelines. This should serve as both a record of decisions made, and a list of open issues.

Do not use doPrivileged() instructions within discovery. That remains the responsibility of the end-user.

commons-discovery-0.5/src/site/xdoc/best-practices.xml0000644000175000017500000002505111547640211023060 0ustar drazzibdrazzib Best Practices for using Apache Commons "Discovery" Component
$Id: best-practices.xml 1090352 2011-04-08 17:06:17Z simonetripodi $
[Introduction] [Discovery Services] [Additional Tools] [Calling Directly] [Integrating into Factories : Wrapping] [Integrating into DI framework: Google Guice]

Best-practices are discussed. See the javadoc, starting with DiscoverySingleton and DiscoverClass, for detail on the API: where service implementations are looked for, the order in which those places are checked, which classloaders are used, and the order in which they are used.

3.1. CALLING DIRECTLY

3.1.1. Finding Singleton Instances (Factories)

DiscoverSingleton finds, loads, and manages the lifecycle of a class implementing a given interface. It only supports classes with default (zero-argument) constructors. DiscoverSingleton can pass a set of properties to the class (see [Service Life Cycle Management]). Use of the term singleton should be applied loosely: DiscoverSingleton will instantiate separate instances of a class if called with different:

  • thread context class loaders (for example, within different web applications in a J2EE managed environment)
  • group contexts (maintain separation between different subsystems, if desired)

To call discovery directly from user-code:

    import org.apache.commons.discovery.DiscoverSingleton; import org.apache.commons.logging.LogFactory; ... LogFactory logFactory = DiscoverSingleton.find(LogFactory.class);
DiscoverSingleton looks for the value of the system property org.apache.commons.logging.LogFactory for the name of a class that implements the LogFactory (abstract) class. Failing that, it uses JDK1.3-style service discovery.

DiscoverSingleton also allows a java.util.Properties parameter to be used for query for service implementation class name, as well as a default implementation class name:

    LogFactory factory = DiscoverSingleton.find(LogFactory.class, properties, LogFactory.FACTORY_DEFAULT);

The properties can also be specified as a resource name:

    LogFactory factory = DiscoverSingleton.find(LogFactory.class, LogFactory.FACTORY_PROPERTIES, LogFactory.FACTORY_DEFAULT);
This last form is equivalent in function to the original LogFactory.getFactory() method.

There are a variety of find methods provided by DiscoverSingleton, review the javadoc for other forms and options available.

3.1.2. Finding Classes

DiscoverClass finds and loads a class implementing a given interface. DiscoverClass can pass a set of properties to the class if it implements the Service interface (which doesn't support full-lifecycle management as does the SingletonService interface).

DiscoverClass provides API's that instantiate a class, though it currently supports only classes with default (zero-argument) constructors. Unlike DiscoverySingleton, class instances are not cached, so each call will result in a new object instance.

DiscoverClass is more oriented toward calling multiple times within similar contexts, so it's use is slightly different than DiscoverSingleton: where as DiscoverSingleton provides a set of static methods (no state), DiscoverClass must be instantiated before it is used and maintains internal state.

To find a class directly from user-code: [NEED BETTER EXAMPLE]

    import org.apache.commons.discovery.DiscoverClasses; import org.apache.commons.logging.LogFactory; ... DiscoverClass discoverClass = new DiscoverClass(); Class<? extends LogFactory> logFactoryClass = discoverClass.find(LogFactory.class);
In this case, DiscoverClass looks for the value of the system property org.apache.commons.logging.LogFactory for the name of a class that implements the LogFactory (abstract) class. Failing that, it uses JDK1.3-style service discovery.

To find all the SPI implementation classes from user-code, use DiscoverClasses instead:

import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.ResourceClass: import org.apache.commons.discovery.resource.classes.DiscoverClasses; import org.apache.commons.logging.LogFactory; ... DiscoverClasses<LogFactory> discovery = new DiscoverClasses<TestInterface2>(loaders); ResourceClassIterator<LogFactory> iter = discovery.findResourceClasses(name); while (iter.hasNext()) { ResourceClass<LogFactory> resource = iter.nextResourceClass(); try { Class<? extends LogFactory> implClass = resource.loadClass(); if (implClass != null) { // TODO do something } } catch (Exception e) { // TODO handle exception } } }

To instantiate a class directly from user-code: [NEED BETTER EXAMPLE]

    import org.apache.commons.discovery.DiscoverClass; import org.apache.commons.logging.LogFactory; ... DiscoverClass discoverClass = new DiscoverClass(); LogFactory logFactoryClass = discoverClass.newInstance(LogFactory.class);

As with DiscoverSingleton, DiscoverClass provides methods that use java.util.Properties and a default implementation class name to help determine the name of the class.

3.2 INTEGRATING INTO FACTORIES : WRAPPING

In this example, a factory (such as is used in commons-logging) internalizes the discovery mechanism, passing appropriate defaults for a default properties file and a default implementation. In this case, the factory plays double duty as both the service to be discovered (abstract class), and the discovery mechanism.

    import java.util.Properties; import org.apache.commons.discovery.DiscoverSingleton; import org.apache.commons.discovery.DiscoveryException; public abstract class LogFactory { protected static final String FACTORY_DEFAULT = org.apache.commons.logging.impl.DefaultLogFactory.class.getName(); protected static final String FACTORY_PROPERTIES = "commons-logging.properties"; /** * Protected constructor that is not available for public use. */ protected LogFactory() { } public static LogFactory getFactory() throws ServiceException { return DiscoverSingleton.find(LogFactory.class, LogFactory.class, FACTORY_PROPERTIES, FACTORY_DEFAULT); } public static LogFactory getFactory(Properties properties) throws ServiceException { return DiscoverSingleton.find(LogFactory.class, LogFactory.class, properties, FACTORY_DEFAULT); } ... }
Note the addition of one extra parameter to the find method call. The first parameter is a root wrapper class, which delegates to the discovery mechanism. This is necessary to all Discovery to determine the correct class loaders to be used in loading an implementation class. The second parameter is the service interface/class for which Discovery will be looking for an implementation. In this example, they are the same class, as the LogFactory is providing helper methods that 'wrap' Discovery.

3.3 INTEGRATING INTO DI FRAMEWORKS : GOOGLE GUICE

Sometimes, a DiscoverSingleton/Factory approach like the one exposed above, is not enough, because you may require injecting dependencies in your discovered SPI.

In this example is shown how DiscoverClass can be useful inside DI framework such Google Guice:

Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { ... DiscoverClass discoverClass = new DiscoverClass(); bind(ServiceInterface.class).to(discoverClass.find(ServiceInterface.class)); ... } });

In this way, ServiceInterface discovery is delegated to Commons Discovery, but concrete class implementation creation and dependencies injection, to Google Guice.

commons-discovery-0.5/src/site/xdoc/mail-lists.xml0000644000175000017500000002232011453122760022222 0ustar drazzibdrazzib Commons Discovery Mailing Lists Commons Documentation Team

Commons Discovery shares mailing lists with all the other Commons Components. To make it easier for people to only read messages related to components they are interested in, the convention in Commons is to prefix the subject line of messages with the component's name, for example:

  • [discovery] Problem with the ...

Questions related to the usage of Commons Discovery should be posted to the User List.
The Developer List is for questions and discussion related to the development of Commons Discovery.
Please do not cross-post; developers are also subscribed to the user list.

Note: please don't send patches or attachments to any of the mailing lists. Patches are best handled via the Issue Tracking system. Otherwise, please upload the file to a public server and include the URL in the mail.

Please prefix the subject line of any messages for Commons Discovery with [discovery] - thanks!

Name Subscribe Unsubscribe Post Archive Other Archives
Commons User List

Questions on using Commons Discovery.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Developer List

Discussion of development of Commons Discovery.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Issues List

Only for e-mails automatically generated by the issue tracking system.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com
Commons Commits List

Only for e-mails automatically generated by the source control sytem.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com

Other mailing lists which you may find useful include:

Name Subscribe Unsubscribe Post Archive Other Archives
Apache Announce List

General announcements of Apache project releases.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
old.nabble.com
www.mail-archive.com
news.gmane.org
commons-discovery-0.5/src/site/xdoc/building.xml0000644000175000017500000000534711546140755021762 0ustar drazzibdrazzib Building Commons Documentation Team

Commons Discovery uses Maven or Ant as a build system.

To build a jar file, change into Discovery's root directory and run mvn package. The result will be in the "target" subdirectory.

To build the Javadocs, run mvn javadoc:javadoc. The result will be in "target/site/apidocs".

To build the full website, run mvn site. The result will be in "target/site".

Further details can be found in the commons build instructions.

To build a jar file and the javadocs, change into Discovery's root directory and run ant dist. The result will be in the "dist" subdirectory.

Nightly Builds are built once a day from the current SVN HEAD. These are provided purely for test purposes and are NOT official releases of the Apache Software Foundation - Released versions of Commons Discovery are available here.

commons-discovery-0.5/src/site/xdoc/index.xml0000644000175000017500000000606310533177605021267 0ustar drazzibdrazzib Discovery: Service Discovery component

The Discovery component is about discovering, or finding, implementations for pluggable interfaces. It provides facilities for instantiating classes in general, and for lifecycle management of singleton (factory) classes.

Fundamentally, Discovery locates classes that implement a given Java interface. The discovery pattern, though not necessarily this package, is used in many projects including JAXP (SaxParserFactory and others) and commons-logging (LogFactory). By extracting this pattern, other projects can (re)use it and take advantage of improvements to the pattern as Discovery evolves.

Discovery improves over previous implementations by establishing facilities for working within managed environments. These allow configuration and property overrides without appealing to the global System properties (which are scoped across an entire JVM).

This is not indended to be a replacement to be used strictly by the user, but rather a replacement to be used directly by projects. Use by the user is also reasonable, but limited due to 'keeping this simple'. In particular, there is no configuration for this discovery service, it relies only on usage patterns.

Given a java.lang.Class parameter 'package.Class' that represents a fundamental service as either an interface, an abstract class (or even a regular class), find an implementation of that class:

  • Look for system property named 'package.Class', the value of which is the name of an implementation.
  • Look for a 'local' property named 'package.Class'...
  • Attempt JDK 1.3+ style discovery
  • Attempt to load a default implementation
In all cases, verify that the discovered implementation implements 'package.Class'.

The package aims to :

  • Have an API which should be as simple to use as possible
  • Be based on usage patterns, not specific configuration file
  • Represent proper discovery & class-loading principles
  • Be reasonably portable across JDK levels (1.1.8+?)

commons-discovery-0.5/src/site/xdoc/download_discovery.xml0000644000175000017500000001551111556057575024065 0ustar drazzibdrazzib Download Commons Discovery Commons Documentation Team

We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from the mirrors.

You are currently using [preferred]. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available.

[if-any logo][end]

Other mirrors:

The KEYS link links to the code signing keys used to sign the product. The PGP link downloads the OpenPGP compatible signature from our main site. The MD5 link downloads the checksum from the main site.

commons-discovery-0.5.tar.gz md5 pgp
commons-discovery-0.5.zip md5 pgp
commons-discovery-0.5-src.tar.gz md5 pgp
commons-discovery-0.5-src.zip md5 pgp

Older releases can be obtained from the archives.

commons-discovery-0.5/src/site/xdoc/issue-tracking.xml0000644000175000017500000001330310762601770023102 0ustar drazzibdrazzib Commons Discovery Issue tracking Commons Documentation Team

Commons Discovery uses ASF JIRA for tracking issues. See the Commons Discovery JIRA project page.

To use JIRA you may need to create an account (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically created and you can use the Forgot Password page to get a new password).

If you would like to report a bug, or raise an enhancement request with Commons Discovery please do the following:

  1. Search existing open bugs. If you find your issue listed then please add a comment with your details.
  2. Search the mailing list archive(s). You may find your issue or idea has already been discussed.
  3. Decide if your issue is a bug or an enhancement.
  4. Submit either a bug report or enhancement request.

Please also remember these points:

  • the more information you provide, the better we can help you
  • test cases are vital, particularly for any proposed enhancements
  • the developers of Commons Discovery are all unpaid volunteers

For more information on subversion and creating patches see the Apache Contributors Guide.

You may also find these links useful:

commons-discovery-0.5/src/java/0000755000175000017500000000000011643422200016434 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/0000755000175000017500000000000011643422200017223 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/0000755000175000017500000000000011643422200020444 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/0000755000175000017500000000000011643422200022117 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/0000755000175000017500000000000011643422201024127 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/log/0000755000175000017500000000000011643422201024710 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/log/package-info.java0000644000175000017500000000157111546710126030113 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Apache Commons-Logging wrapper. */ package org.apache.commons.discovery.log; commons-discovery-0.5/src/java/org/apache/commons/discovery/log/DiscoveryLogFactory.java0000644000175000017500000001275211546707311031535 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.log; import java.lang.reflect.Method; import java.util.Hashtable; import java.util.Map; import org.apache.commons.discovery.DiscoveryException; import org.apache.commons.discovery.tools.ClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** *

Simple implementation of Log that sends all enabled log messages, * for all defined loggers, to System.err. *

* *

Hacked from commons-logging SimpleLog for use in discovery. * This is intended to be enough of a Log implementation to bootstrap * Discovery. *

* *

One property: org.apache.commons.discovery.log.level. * valid values: all, trace, debug, info, warn, error, fatal, off. *

* * @deprecated Starting from commons-discovery-05, Log is totally delegated to commons-logging * @version $Id: DiscoveryLogFactory.java 1089255 2011-04-05 21:51:05Z simonetripodi $ */ @Deprecated public class DiscoveryLogFactory { private static LogFactory logFactory = null; private static final Map, Class> classRegistry = new Hashtable, Class>(); private static final Class[] setLogParamClasses = new Class[] { Log.class }; /** * Above fields must be initialied before this one.. */ private static Log log = DiscoveryLogFactory._newLog(DiscoveryLogFactory.class); /** * Creates a new {@code Log} instance for the input class. * * @param clazz The class the log has to be created for * @return The input class logger */ public static Log newLog(Class clazz) { /** * Required to implement 'public static void setLog(Log)' */ try { Method setLog = ClassUtils.findPublicStaticMethod(clazz, void.class, "setLog", setLogParamClasses); if (setLog == null) { String msg = "Internal Error: " + clazz.getName() + " required to implement 'public static void setLog(Log)'"; log.fatal(msg); throw new DiscoveryException(msg); } } catch (SecurityException se) { String msg = "Required Security Permissions not present"; log.fatal(msg, se); throw new DiscoveryException(msg, se); } if (log.isDebugEnabled()) { log.debug("Class meets requirements: " + clazz.getName()); } return _newLog(clazz); } /** * This method MUST not invoke any logging.. * * @param clazz The class the log has to be created for * @return The input class logger */ public static Log _newLog(Class clazz) { classRegistry.put(clazz, clazz); return (logFactory == null) ? new SimpleLog(clazz.getName()) : logFactory.getInstance(clazz.getName()); } /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} */ public static void setLog(Log _log) { log = _log; } /** * Set logFactory, works ONLY on first call. * * @param factory The log factory */ public static void setFactory(LogFactory factory) { if (logFactory == null) { // for future generations.. if any logFactory = factory; // now, go back and reset loggers for all current classes.. for (Class clazz : classRegistry.values()) { if (log.isDebugEnabled()) { log.debug("Reset Log for: " + clazz.getName()); } Method setLog = null; // invoke 'setLog(Log)'.. we already know it's 'public static', // have verified parameters, and return type.. try { setLog = clazz.getMethod("setLog", setLogParamClasses); } catch(Exception e) { String msg = "Internal Error: pre-check for " + clazz.getName() + " failed?!"; log.fatal(msg, e); throw new DiscoveryException(msg, e); } Object[] setLogParam = new Object[] { factory.getInstance(clazz.getName()) }; try { setLog.invoke(null, setLogParam); } catch(Exception e) { String msg = "Internal Error: setLog failed for " + clazz.getName(); log.fatal(msg, e); throw new DiscoveryException(msg, e); } } } } } commons-discovery-0.5/src/java/org/apache/commons/discovery/log/SimpleLog.java0000644000175000017500000003463611547102270027466 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.log; import java.io.PrintStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.logging.Log; /** *

Simple implementation of Log that sends all enabled log messages, * for all defined loggers, to System.err. *

* *

Hacked from commons-logging SimpleLog for use in discovery. * This is intended to be enough of a Log implementation to bootstrap * Discovery. *

* *

One property: org.apache.commons.discovery.log.level. * valid values: all, trace, debug, info, warn, error, fatal, off. *

* * @deprecated Starting from commons-discovery-05, Log is totally delegated to commons-logging * @version $Id: SimpleLog.java 1089489 2011-04-06 15:20:24Z sebb $ */ @Deprecated public class SimpleLog implements Log { // ---------------------------------------------------- Log Level Constants /** "Trace" level logging. */ public static final int LOG_LEVEL_TRACE = 1; /** "Debug" level logging. */ public static final int LOG_LEVEL_DEBUG = 2; /** "Info" level logging. */ public static final int LOG_LEVEL_INFO = 3; /** "Warn" level logging. */ public static final int LOG_LEVEL_WARN = 4; /** "Error" level logging. */ public static final int LOG_LEVEL_ERROR = 5; /** "Fatal" level logging. */ public static final int LOG_LEVEL_FATAL = 6; /** Enable all logging levels */ public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1); /** Enable no logging levels */ public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1); // ------------------------------------------------------- Class Attributes static protected final String PROP_LEVEL = "org.apache.commons.discovery.log.level"; /** Include the instance name in the log message? */ static protected boolean showLogName = false; /** Include the short name ( last component ) of the logger in the log message. Default to true - otherwise we'll be lost in a flood of messages without knowing who sends them. */ static protected boolean showShortName = true; /** Include the current time in the log message */ static protected boolean showDateTime = false; /** Used to format times */ static protected DateFormat dateFormatter = null; /** The current log level */ static protected int logLevel = LOG_LEVEL_INFO; /** * Use 'out' instead of 'err' for logging * to keep in-sync with test messages. */ static private PrintStream out = System.out; // ------------------------------------------------------------ Initializer // initialize class attributes static { if(showDateTime) { dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS zzz"); } try { // set log level from properties String lvl = System.getProperty(PROP_LEVEL); if("all".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_ALL); } else if("trace".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_TRACE); } else if("debug".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_DEBUG); } else if("info".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_INFO); } else if("warn".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_WARN); } else if("error".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_ERROR); } else if("fatal".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_FATAL); } else if("off".equalsIgnoreCase(lvl)) { setLevel(SimpleLog.LOG_LEVEL_OFF); } } catch (SecurityException ignored) { //do nothing. We get here if running discovery //under a servlet with restricted security rights, and //cannot read the system property. //In which case, the default is what you get to keep. } } // -------------------------------------------------------- Properties /** *

Set logging level.

* * @param currentLogLevel new logging level */ public static void setLevel(int currentLogLevel) { logLevel = currentLogLevel; } /** * Get logging level. * * @return The logging level */ public static int getLevel() { return logLevel; } /** * Is the given log level currently enabled? * * @param level is this level enabled? * @return true, if the input level is enabled, false otherwise */ protected static boolean isLevelEnabled(int level) { // log level are numerically ordered so can use simple numeric // comparison return (level >= getLevel()); } // ------------------------------------------------------------- Attributes /** The name of this simple log instance */ protected String logName = null; private String prefix=null; // ------------------------------------------------------------ Constructor /** * Construct a simple log with given name. * * @param name log name */ public SimpleLog(String name) { logName = name; } // -------------------------------------------------------- Logging Methods /** * Do the actual logging. * * This method assembles the message and then prints to {@code System.err}. * * @param type The logging level * @param message The message to log * @param t The error cause, if any */ protected void log(int type, Object message, Throwable t) { // use a string buffer for better performance StringBuffer buf = new StringBuffer(); // append date-time if so configured if(showDateTime) { buf.append(dateFormatter.format(new Date())); buf.append(" "); } // append a readable representation of the log leve switch(type) { case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break; case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break; case SimpleLog.LOG_LEVEL_INFO: buf.append("[INFO ] "); break; case SimpleLog.LOG_LEVEL_WARN: buf.append("[WARN ] "); break; case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break; case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break; } // append the name of the log instance if so configured if( showShortName) { if( prefix==null ) { // cut all but the last component of the name for both styles prefix = logName.substring( logName.lastIndexOf(".") +1) + " - "; prefix = prefix.substring( prefix.lastIndexOf("/") +1) + "-"; } buf.append( prefix ); } else if(showLogName) { buf.append(String.valueOf(logName)).append(" - "); } // append the message buf.append(String.valueOf(message)); // append stack trace if not null if(t != null) { buf.append(" <"); buf.append(t.toString()); buf.append(">"); } // print to System.err out.println(buf.toString()); if (t != null) { t.printStackTrace(System.err); } } // -------------------------------------------------------- Log Implementation /** * Log a message with debug log level. * * @param message The message to log */ public final void debug(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) { log(SimpleLog.LOG_LEVEL_DEBUG, message, null); } } /** * Log an error with debug log level. * * @param message The message to log * @param t The error cause, if any */ public final void debug(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) { log(SimpleLog.LOG_LEVEL_DEBUG, message, t); } } /** * Log a message with debug log level. * * @param message The message to log */ public final void trace(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) { log(SimpleLog.LOG_LEVEL_TRACE, message, null); } } /** * Log an error with debug log level. * * @param message The message to log * @param t The error cause, if any */ public final void trace(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) { log(SimpleLog.LOG_LEVEL_TRACE, message, t); } } /** * Log a message with info log level. * * @param message The message to log */ public final void info(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) { log(SimpleLog.LOG_LEVEL_INFO,message,null); } } /** * Log an error with info log level. * * @param message The message to log * @param t The error cause, if any */ public final void info(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) { log(SimpleLog.LOG_LEVEL_INFO, message, t); } } /** * Log a message with warn log level. * * @param message The message to log */ public final void warn(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) { log(SimpleLog.LOG_LEVEL_WARN, message, null); } } /** * Log an error with warn log level. * * @param message The message to log * @param t The error cause, if any */ public final void warn(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) { log(SimpleLog.LOG_LEVEL_WARN, message, t); } } /** * Log a message with error log level. * * @param message The message to log */ public final void error(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) { log(SimpleLog.LOG_LEVEL_ERROR, message, null); } } /** * Log an error with error log level. * * @param message The message to log * @param t The error cause, if any */ public final void error(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) { log(SimpleLog.LOG_LEVEL_ERROR, message, t); } } /** * Log a message with fatal log level. * * @param message The message to log */ public final void fatal(Object message) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) { log(SimpleLog.LOG_LEVEL_FATAL, message, null); } } /** * Log an error with fatal log level. * * @param message The message to log * @param t The error cause, if any */ public final void fatal(Object message, Throwable t) { if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) { log(SimpleLog.LOG_LEVEL_FATAL, message, t); } } /** *

Are debug messages currently enabled?

* *

This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger.

* * @return true, if the {@link SimpleLog#LOG_LEVEL_DEBUG} is enabled, false otherwise */ public final boolean isDebugEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG); } /** *

Are error messages currently enabled?

* *

This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger.

* * @return true, if the {@link SimpleLog#LOG_LEVEL_ERROR} is enabled, false otherwise */ public final boolean isErrorEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR); } /** *

Are fatal messages currently enabled?

* *

This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger.

* * @return true, if the {@link SimpleLog#LOG_LEVEL_FATAL} is enabled, false otherwise */ public final boolean isFatalEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL); } /** *

Are info messages currently enabled?

* *

This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger.

* * @return true, if the {@link SimpleLog#LOG_LEVEL_INFO} is enabled, false otherwise */ public final boolean isInfoEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO); } /** *

Are trace messages currently enabled?

* *

This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger.

* * @return true, if the {@link SimpleLog#LOG_LEVEL_TRACE} is enabled, false otherwise */ public final boolean isTraceEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE); } /** *

Are warn messages currently enabled?

* *

This allows expensive operations such as String * concatenation to be avoided when the message will be ignored by the * logger.

* * @return true, if the {@link SimpleLog#LOG_LEVEL_WARN} is enabled, false otherwise */ public final boolean isWarnEnabled() { return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/package-info.java0000644000175000017500000000177411545717577027357 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Highlights: *
    *
  • JDK 1.3 Service discovery
  • *
  • Discovery supports JDK 1.1.8 and up (see org.apache.commons.discover.jdk.JDKHooks). *
  • *
*/ package org.apache.commons.discovery; commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceNameDiscover.java0000644000175000017500000000303511546563027031100 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * Interface representing a mapping * from a set of source resource names * to a resultant set of resource names. */ public interface ResourceNameDiscover { /** * Locate names of resources that are bound to {@code resourceName}. * * @param resourceName The resource has to be located * @return The bound resources name iterator */ ResourceNameIterator findResourceNames(String resourceName); /** * Locate names of resources that are bound to {@code resourceNames}. * * @param resourceNames The resources has to be located * @return The bound resources name iterator */ ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames); } commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceClass.java0000644000175000017500000001063511547556500027571 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 'Resource' located by discovery. * Naming of methods becomes a real pain ('getClass()') * so I've patterned this after ClassLoader... * * I think it works well as it will give users a point-of-reference. * * @param The SPI type */ public class ResourceClass extends Resource { private static Log log = LogFactory.getLog(ResourceClass.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } protected Class resourceClass; /** * Create a new {@code Resource} class located by discovery. * * @param Any type extends T * @param resourceClass The resource class has to be located * @param resource The resource URL has to be located */ public ResourceClass(Class resourceClass, URL resource) { super(resourceClass.getName(), resource, resourceClass.getClassLoader()); this.resourceClass = resourceClass; } /** * Create a new {@code Resource} class located by discovery. * * @param resourceName The resource class name has to be located * @param resource The resource URL has to be located * @param loader The class loaders holder */ public ResourceClass(String resourceName, URL resource, ClassLoader loader) { super(resourceName, resource, loader); } /** * Get the value of resourceClass. * Loading the class does NOT guarentee that the class can be * instantiated. Go figure. * The class can be instantiated when the class is linked/resolved, * and all dependencies are resolved. * Various JDKs do this at different times, so beware: * java.lang.NoClassDefFoundError when * calling Class.getDeclaredMethod() (JDK14), * java.lang.reflect.InvocationTargetException * (wrapping java.lang.NoClassDefFoundError) when calling * java.lang.newInstance (JDK13), * and who knows what else.. * * @param Any type extends T * * @return value of resourceClass. */ public Class loadClass() { if (resourceClass == null && getClassLoader() != null) { if (log.isDebugEnabled()) { log.debug("loadClass: Loading class '" + getName() + "' with " + getClassLoader()); } resourceClass = AccessController.doPrivileged( new PrivilegedAction>() { public Class run() { try { @SuppressWarnings("unchecked") // this can raise a ClassCastException at runtime Class returned = (Class) getClassLoader().loadClass(getName()); return returned; } catch (ClassNotFoundException e) { return null; } } }); } @SuppressWarnings("unchecked") // this is assumed by default, see the ctor Class returned = (Class) resourceClass; return returned; } /** * {@inheritDoc} */ @Override public String toString() { return "ResourceClass[" + getName() + ", " + getResource() + ", " + getClassLoader() + "]"; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/0000755000175000017500000000000011643422201025267 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/tools/package-info.java0000644000175000017500000000157411546710126030475 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Discovery tools implementations. */ package org.apache.commons.discovery.tools; commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/DiscoverSingleton.java0000644000175000017500000004643711546705241031623 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.apache.commons.discovery.DiscoveryException; import org.apache.commons.discovery.jdk.JDKHooks; import org.apache.commons.discovery.resource.ClassLoaders; /** *

Discover singleton service providers. * This *

* *

DiscoverSingleton instances are cached by the Discovery service, * keyed by a combination of *

    *
  • thread context class loader,
  • *
  • groupContext, and
  • *
  • SPI.
  • *
* This DOES allow multiple instances of a given singleton class * to exist for different class loaders and different group contexts. *

* *

In the context of this package, a service interface is defined by a * Service Provider Interface (SPI). The SPI is expressed as a Java interface, * abstract class, or (base) class that defines an expected programming * interface. *

* *

DiscoverSingleton provides the find methods for locating and * instantiating a singleton instance of an implementation of a service (SPI). * Each form of find varies slightly, but they all perform the * same basic function. * * The simplest find methods are intended for direct use by * components looking for a service. If you are not sure which finder(s) * to use, you can narrow your search to one of these: *

    *
  • static <T> T find(Class<T> spi);
  • *
  • static <T> T find(Class<T> spi, Properties properties);
  • *
  • static <T> T find(Class<T> spi, String defaultImpl);
  • *
  • static <T> T find(Class<T> spi, * Properties properties, String defaultImpl);
  • *
  • static <T> T find(Class<T> spi, * String propertiesFileName, String defaultImpl);
  • *
  • static <T> T find(ClassLoaders loaders, SPInterface<T> spi, * PropertiesHolder holder, DefaultClassHolder<T> holder);
  • *
* * The DiscoverSingleton.find methods proceed as follows: *

*
    *

  • * Examine an internal cache to determine if the desired service was * previously identified and instantiated. If found in cache, return it. *
  • *

  • * Get the name of an implementation class. The name is the first * non-null value obtained from the following resources: *
      *
    • * The value of the (scoped) system property whose name is the same as * the SPI's fully qualified class name (as given by SPI.class.getName()). * The ScopedProperties class provides a way to bind * properties by classloader, in a secure hierarchy similar in concept * to the way classloader find class and resource files. * See ScopedProperties for more details. *

      If the ScopedProperties are not set by users, then behaviour * is equivalent to System.getProperty(). *

      *
    • *

    • * The value of a Properties properties property, if provided * as a parameter, whose name is the same as the SPI's fully qualifed class * name (as given by SPI.class.getName()). *
    • *

    • * The value obtained using the JDK1.3+ 'Service Provider' specification * (http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html) to locate a * service named SPI.class.getName(). This is implemented * internally, so there is not a dependency on JDK 1.3+. *
    • *
    *
  • *

  • * If the name of the implementation class is non-null, load that class. * The class loaded is the first class loaded by the following sequence * of class loaders: *
      *
    • Thread Context Class Loader
    • *
    • DiscoverSingleton's Caller's Class Loader
    • *
    • SPI's Class Loader
    • *
    • DiscoverSingleton's (this class or wrapper) Class Loader
    • *
    • System Class Loader
    • *
    * An exception is thrown if the class cannot be loaded. *
  • *

  • * If the name of the implementation class is null, AND the default * implementation class (defaultImpl) is null, * then an exception is thrown. *
  • *

  • * If the name of the implementation class is null, AND the default * implementation class (defaultImpl) is non-null, * then load the default implementation class. The class loaded is the * first class loaded by the following sequence of class loaders: *
      *
    • SPI's Class Loader
    • *
    • DiscoverSingleton's (this class or wrapper) Class Loader
    • *
    • System Class Loader
    • *
    *

    * This limits the scope in which the default class loader can be found * to the SPI, DiscoverSingleton, and System class loaders. The assumption * here is that the default implementation is closely associated with the SPI * or system, and is not defined in the user's application space. *

    *

    * An exception is thrown if the class cannot be loaded. *

    *
  • *

  • * Verify that the loaded class implements the SPI: an exception is thrown * if the loaded class does not implement the SPI. *
  • *

  • * Create an instance of the class. *
  • *
* *

* Variances for various forms of the find * methods are discussed with each such method. * Variances include the following concepts: *

    *
  • rootFinderClass - a wrapper encapsulating a finder method * (factory or other helper class). The root finder class is used to * determine the 'real' caller, and hence the caller's class loader - * thereby preserving knowledge that is relevant to finding the * correct/expected implementation class. *
  • *
  • propertiesFileName - Properties may be specified * directly, or by property file name. A property file is loaded using the * same sequence of class loaders used to load the SPI implementation: *
      *
    • Thread Context Class Loader
    • *
    • DiscoverSingleton's Caller's Class Loader
    • *
    • SPI's Class Loader
    • *
    • DiscoverSingleton's (this class) Class Loader
    • *
    • System Class Loader
    • *
    *
  • *
  • groupContext - differentiates service providers for different * logical groups of service users, that might otherwise be forced to share * a common service and, more importantly, a common configuration of that * service. *

    The groupContext is used to qualify the name of the property file * name: groupContext + '.' + propertiesFileName. If that * file is not found, then the unqualified propertyFileName is used. *

    *

    In addition, groupContext is used to qualify the name of the system * property used to find the service implementation by prepending the value * of groupContext to the property name: * groupContext> + '.' + SPI.class.getName(). * Again, if a system property cannot be found by that name, then the * unqualified property name is used. *

    *
  • *
*

* *

IMPLEMENTATION NOTE - This implementation is modelled * after the SAXParserFactory and DocumentBuilderFactory implementations * (corresponding to the JAXP pluggability APIs) found in Apache Xerces. *

* * @version $Revision: 1089242 $ $Date: 2011-04-05 23:33:21 +0200 (mar. 05 avril 2011) $ */ public class DiscoverSingleton { /********************** (RELATIVELY) SIMPLE FINDERS ********************** * * These finders are suitable for direct use in components looking for a * service. If you are not sure which finder(s) to use, you can narrow * your search to one of these. */ /** * Find implementation of SPI. * * @param Service Provider Interface type. * @param spiClass Service Provider Interface Class. * * @return Instance of a class implementing the SPI. * * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static T find(Class spiClass) throws DiscoveryException { return find(null, new SPInterface(spiClass), DiscoverClass.nullProperties, (DefaultClassHolder) null); } /** * Find implementation of SPI. * * @param Service Provider Interface type * * @param spiClass Service Provider Interface Class. * * @param properties Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * * @return Instance of a class implementing the SPI. * * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static T find(Class spiClass, Properties properties) throws DiscoveryException { return find(null, new SPInterface(spiClass), new PropertiesHolder(properties), (DefaultClassHolder) null); } /** * Find implementation of SPI. * * @param Service Provider Interface type * * @param spiClass Service Provider Interface Class. * * @param defaultImpl Default implementation. * * @return Instance of a class implementing the SPI. * * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static T find(Class spiClass, String defaultImpl) throws DiscoveryException { return find(null, new SPInterface(spiClass), DiscoverClass.nullProperties, new DefaultClassHolder(defaultImpl)); } /** * Find implementation of SPI. * * @param Service Provider Interface type * * @param spiClass Service Provider Interface Class. * * @param properties Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * * @param defaultImpl Default implementation. * * @return Instance of a class implementing the SPI. * * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static T find(Class spiClass, Properties properties, String defaultImpl) throws DiscoveryException { return find(null, new SPInterface(spiClass), new PropertiesHolder(properties), new DefaultClassHolder(defaultImpl)); } /** * Find implementation of SPI. * * @param Service Provider Interface type * * @param spiClass Service Provider Interface Class. * * @param propertiesFileName Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * * @param defaultImpl Default implementation. * * @return Instance of a class implementing the SPI. * * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static T find(Class spiClass, String propertiesFileName, String defaultImpl) throws DiscoveryException { return find(null, new SPInterface(spiClass), new PropertiesHolder(propertiesFileName), new DefaultClassHolder(defaultImpl)); } /*************** FINDERS FOR USE IN FACTORY/HELPER METHODS *************** */ /** * Find implementation of SPI. * * @param Service Provider Interface type * * @param loaders The {@code ClassLoader} holder * * @param spi Service Provider Interface Class. * * @param properties Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * * @param defaultImpl Default implementation. * * @return Instance of a class implementing the SPI. * * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static T find(ClassLoaders loaders, SPInterface spi, PropertiesHolder properties, DefaultClassHolder defaultImpl) throws DiscoveryException { ClassLoader contextLoader = JDKHooks.getJDKHooks().getThreadContextClassLoader(); @SuppressWarnings("unchecked") // spiName is assignable from stored object class T obj = (T) get(contextLoader, spi.getSPName()); if (obj == null) { try { obj = DiscoverClass.newInstance(loaders, spi, properties, defaultImpl); if (obj != null) { put(contextLoader, spi.getSPName(), obj); } } catch (DiscoveryException de) { throw de; } catch (Exception e) { throw new DiscoveryException("Unable to instantiate implementation class for " + spi.getSPName(), e); } } return obj; } /********************** CACHE-MANAGEMENT SUPPORT **********************/ /** * Release all internal references to previously created service * instances associated with the current thread context class loader. * The release() method is called for service instances that * implement the Service interface. * * This is useful in environments like servlet containers, * which implement application reloading by throwing away a ClassLoader. * Dangling references to objects in that class loader would prevent * garbage collection. */ public static synchronized void release() { EnvironmentCache.release(); } /** * Release any internal references to a previously created service * instance associated with the current thread context class loader. * If the SPI instance implements Service, then call * release(). * * @param spiClass The previously created service */ public static synchronized void release(Class spiClass) { Map spis = EnvironmentCache.get(JDKHooks.getJDKHooks().getThreadContextClassLoader()); if (spis != null) { spis.remove(spiClass.getName()); } } /************************* SPI CACHE SUPPORT ************************* * * Cache services by a 'key' unique to the requesting class/environment: * * When we 'release', it is expected that the caller of the 'release' * have the same thread context class loader... as that will be used * to identify all cached entries to be released. * * We will manage synchronization directly, so all caches are implemented * as HashMap (unsynchronized). * * - ClassLoader::groupContext::SPI::Instance Cache * Cache : HashMap * Key : Thread Context Class Loader (ClassLoader). * Value : groupContext::SPI Cache (HashMap). * * - groupContext::SPI::Instance Cache * Cache : HashMap * Key : groupContext (String). * Value : SPI Cache (HashMap). * * - SPI::Instance Cache * Cache : HashMap * Key : SPI Class Name (String). * Value : SPI Instance/Implementation (Object. */ /** * Implements first two levels of the cache (loader & groupContext). * Allows null keys, important as default groupContext is null. */ /** * Get service keyed by spi & classLoader. * * @param classLoader The class loader as key to retrieve the related cache * @param spiName The SPI class name * @return The object instance associated to the given class loader/SPI name */ private static synchronized Object get(ClassLoader classLoader, String spiName) { Map spis = EnvironmentCache.get(classLoader); if (spis != null) { return spis.get(spiName); } return null; } /** * Put service keyed by spi & classLoader. * * @param classLoader The {@link EnvironmentCache} key * @param spiName The SPI class name * @param service The SPI object reference */ private static synchronized void put(ClassLoader classLoader, String spiName, Object service) { if (service != null) { Map spis = EnvironmentCache.get(classLoader); if (spis == null) { spis = new HashMap(EnvironmentCache.smallHashSize); EnvironmentCache.put(classLoader, spis); } spis.put(spiName, service); } } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/DefaultClassHolder.java0000644000175000017500000000662211546667004031666 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import org.apache.commons.discovery.ResourceClass; import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.resource.classes.DiscoverClasses; import org.apache.commons.discovery.resource.ClassLoaders; /** * Holder for a default class. * * Class may be specified by name (String) or class (Class). * Using the holder complicates the users job, but minimized # of API's. */ public class DefaultClassHolder { private Class defaultClass; private final String defaultName; /** * Creates a new holder implementation given * the input SPI implementation/extension class. * * @param Any type extends the SPI type * @param defaultClass The hold class */ public DefaultClassHolder(Class defaultClass) { this.defaultClass = defaultClass; this.defaultName = defaultClass.getName(); } /** * Creates a new holder implementation given * the input SPI implementation/extension class name. * * @param defaultName The hold class name */ public DefaultClassHolder(String defaultName) { this.defaultClass = null; this.defaultName = defaultName; } /** * Returns the default class, loading it if necessary * and verifying that it implements the SPI * (this forces the check, no way out..). * * @param Any type extends the SPI type * @param spi non-null SPI * @param loaders Used only if class needs to be loaded. * @return The default Class. */ public Class getDefaultClass(SPInterface spi, ClassLoaders loaders) { if (defaultClass == null) { DiscoverClasses classDiscovery = new DiscoverClasses(loaders); ResourceClassIterator classes = classDiscovery.findResourceClasses(getDefaultName()); if (classes.hasNext()) { ResourceClass info = classes.nextResourceClass(); try { defaultClass = info.loadClass(); } catch (Exception e) { // ignore } } } if (defaultClass != null) { spi.verifyAncestory(defaultClass); } @SuppressWarnings("unchecked") // the SPInterface.verifyAncestory already asserted Class returned = (Class) defaultClass; return returned; } /** * Returns the hold class name. * * @return The hold class name */ public String getDefaultName() { return defaultName; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/DiscoverClass.java0000644000175000017500000006211211547423466030721 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.lang.reflect.InvocationTargetException; import java.util.LinkedList; import java.util.List; import java.util.Properties; import org.apache.commons.discovery.DiscoveryException; import org.apache.commons.discovery.ResourceClass; import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.discovery.resource.classes.DiscoverClasses; import org.apache.commons.discovery.resource.names.DiscoverServiceNames; /** *

Discover class that implements a given service interface, * with discovery and configuration features similar to that employed * by standard Java APIs such as JAXP. *

* *

In the context of this package, a service interface is defined by a * Service Provider Interface (SPI). The SPI is expressed as a Java interface, * abstract class, or (base) class that defines an expected programming * interface. *

* *

DiscoverClass provides the find methods for locating a * class that implements a service interface (SPI). Each form of * find varies slightly, but they all perform the same basic * function. * * The DiscoverClass.find methods proceed as follows: *

*
    *

  • * Get the name of an implementation class. The name is the first * non-null value obtained from the following resources: *
      *
    • * The value of the (scoped) system property whose name is the same as * the SPI's fully qualified class name (as given by SPI.class.getName()). * The ScopedProperties class provides a way to bind * properties by classloader, in a secure hierarchy similar in concept * to the way classloader find class and resource files. * See ScopedProperties for more details. *

      If the ScopedProperties are not set by users, then behaviour * is equivalent to System.getProperty(). *

      *
    • *

    • * The value of a Properties properties property, if provided * as a parameter, whose name is the same as the SPI's fully qualifed class * name (as given by SPI.class.getName()). *
    • *

    • * The value obtained using the JDK1.3+ 'Service Provider' specification * (http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html) to locate a * service named SPI.class.getName(). This is implemented * internally, so there is not a dependency on JDK 1.3+. *
    • *
    *
  • *

  • * If the name of the implementation class is non-null, load that class. * The class loaded is the first class loaded by the following sequence * of class loaders: *
      *
    • Thread Context Class Loader
    • *
    • DiscoverSingleton's Caller's Class Loader
    • *
    • SPI's Class Loader
    • *
    • DiscoverSingleton's (this class or wrapper) Class Loader
    • *
    • System Class Loader
    • *
    * An exception is thrown if the class cannot be loaded. *
  • *

  • * If the name of the implementation class is null, AND the default * implementation class name (defaultImpl) is null, * then an exception is thrown. *
  • *

  • * If the name of the implementation class is null, AND the default * implementation class (defaultImpl) is non-null, * then load the default implementation class. The class loaded is the * first class loaded by the following sequence of class loaders: *
      *
    • SPI's Class Loader
    • *
    • DiscoverSingleton's (this class or wrapper) Class Loader
    • *
    • System Class Loader
    • *
    *

    * This limits the scope in which the default class loader can be found * to the SPI, DiscoverSingleton, and System class loaders. The assumption here * is that the default implementation is closely associated with the SPI * or system, and is not defined in the user's application space. *

    *

    * An exception is thrown if the class cannot be loaded. *

    *
  • *

  • * Verify that the loaded class implements the SPI: an exception is thrown * if the loaded class does not implement the SPI. *
  • *
*

* *

IMPLEMENTATION NOTE - This implementation is modelled * after the SAXParserFactory and DocumentBuilderFactory implementations * (corresponding to the JAXP pluggability APIs) found in Apache Xerces. *

* * @version $Revision: 1090010 $ $Date: 2011-04-07 23:05:58 +0200 (jeu. 07 avril 2011) $ */ public class DiscoverClass { /** * Readable placeholder for a null value. */ public static final PropertiesHolder nullProperties = null; /** * The class loaders holder. */ private final ClassLoaders classLoaders; /** * Create a class instance with dynamic environment * (thread context class loader is determined on each call). * * Dynamically construct class loaders on each call. */ public DiscoverClass() { this(null); } /** * Create a class instance with dynamic environment * (thread context class loader is determined on each call). * * Cache static list of class loaders for each call. * * @param classLoaders The class loaders holder */ public DiscoverClass(ClassLoaders classLoaders) { this.classLoaders = classLoaders; } /** * Return the class loaders holder for the given SPI. * * @param spiClass The SPI type * @return The class loaders holder for the given SPI */ public ClassLoaders getClassLoaders(@SuppressWarnings("unused") Class spiClass) { return classLoaders; } /** * Find class implementing SPI. * * @param The SPI type * @param Any class extending T * @param spiClass Service Provider Interface Class. * @return Class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded, or if * the resulting class does not implement (or extend) the SPI. */ public Class find(Class spiClass) throws DiscoveryException { return find(getClassLoaders(spiClass), new SPInterface(spiClass), nullProperties, (DefaultClassHolder) null); } /** * Find class implementing SPI. * * @param The SPI type * @param Any class extending T * @param spiClass Service Provider Interface Class. * @param properties Used to determine name of SPI implementation. * @return Class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded, or if * the resulting class does not implement (or extend) the SPI. */ public Class find(Class spiClass, Properties properties) throws DiscoveryException { return find(getClassLoaders(spiClass), new SPInterface(spiClass), new PropertiesHolder(properties), (DefaultClassHolder) null); } /** * Find class implementing SPI. * * @param The SPI type * @param Any class extending T * @param spiClass Service Provider Interface Class. * @param defaultImpl Default implementation name. * @return Class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded, or if * the resulting class does not implement (or extend) the SPI. */ public Class find(Class spiClass, String defaultImpl) throws DiscoveryException { return find(getClassLoaders(spiClass), new SPInterface(spiClass), nullProperties, new DefaultClassHolder(defaultImpl)); } /** * Find class implementing SPI. * * @param The SPI type * @param Any class extending T * @param spiClass Service Provider Interface Class. * @param properties Used to determine name of SPI implementation,. * @param defaultImpl Default implementation class. * @return Class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded, or if * the resulting class does not implement (or extend) the SPI. */ public Class find(Class spiClass, Properties properties, String defaultImpl) throws DiscoveryException { return find(getClassLoaders(spiClass), new SPInterface(spiClass), new PropertiesHolder(properties), new DefaultClassHolder(defaultImpl)); } /** * Find class implementing SPI. * * @param The SPI type * @param Any class extending T * @param spiClass Service Provider Interface Class. * @param propertiesFileName Used to determine name of SPI implementation,. * @param defaultImpl Default implementation class. * @return Class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded, or if * the resulting class does not implement (or extend) the SPI. */ public Class find(Class spiClass, String propertiesFileName, String defaultImpl) throws DiscoveryException { return find(getClassLoaders(spiClass), new SPInterface(spiClass), new PropertiesHolder(propertiesFileName), new DefaultClassHolder(defaultImpl)); } /** * Find class implementing SPI. * * @param The SPI type * @param Any class extending T * @param loaders The class loaders holder * @param spi Service Provider Interface Class. * @param properties Used to determine name of SPI implementation,. * @param defaultImpl Default implementation class. * @return Class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded, or if * the resulting class does not implement (or extend) the SPI. */ public static Class find(ClassLoaders loaders, SPInterface spi, PropertiesHolder properties, DefaultClassHolder defaultImpl) throws DiscoveryException { if (loaders == null) { loaders = ClassLoaders.getLibLoaders(spi.getSPClass(), DiscoverClass.class, true); } Properties props = (properties == null) ? null : properties.getProperties(spi, loaders); String[] classNames = discoverClassNames(spi, props); Exception error = null; if (classNames.length > 0) { DiscoverClasses classDiscovery = new DiscoverClasses(loaders); for (String className : classNames) { ResourceClassIterator classes = classDiscovery.findResourceClasses(className); // If it's set as a property.. it had better be there! if (classes.hasNext()) { ResourceClass info = classes.nextResourceClass(); try { return info.loadClass(); } catch (Exception e) { error = e; } } } } else { ResourceNameIterator classIter = (new DiscoverServiceNames(loaders)).findResourceNames(spi.getSPName()); ResourceClassIterator classes = (new DiscoverClasses(loaders)).findResourceClasses(classIter); if (!classes.hasNext() && defaultImpl != null) { return defaultImpl.getDefaultClass(spi, loaders); } // Services we iterate through until we find one that loads.. while (classes.hasNext()) { ResourceClass info = classes.nextResourceClass(); try { return info.loadClass(); } catch (Exception e) { error = e; } } } throw new DiscoveryException("No implementation defined for " + spi.getSPName(), error); // return null; } /** * Create new instance of class implementing SPI. * * @param The SPI type * @param spiClass Service Provider Interface Class. * @return Instance of a class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public T newInstance(Class spiClass) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { return newInstance(getClassLoaders(spiClass), new SPInterface(spiClass), nullProperties, (DefaultClassHolder) null); } /** * Create new instance of class implementing SPI. * * @param The SPI type * @param spiClass Service Provider Interface Class. * @param properties Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * @return Instance of a class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public T newInstance(Class spiClass, Properties properties) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { return newInstance(getClassLoaders(spiClass), new SPInterface(spiClass), new PropertiesHolder(properties), (DefaultClassHolder) null); } /** * Create new instance of class implementing SPI. * * @param The SPI type * @param spiClass Service Provider Interface Class. * @param defaultImpl Default implementation. * @return Instance of a class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public T newInstance(Class spiClass, String defaultImpl) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { return newInstance(getClassLoaders(spiClass), new SPInterface(spiClass), nullProperties, new DefaultClassHolder(defaultImpl)); } /** * Create new instance of class implementing SPI. * * @param The SPI type * @param spiClass Service Provider Interface Class. * @param properties Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * @param defaultImpl Default implementation. * @return Instance of a class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public T newInstance(Class spiClass, Properties properties, String defaultImpl) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { return newInstance(getClassLoaders(spiClass), new SPInterface(spiClass), new PropertiesHolder(properties), new DefaultClassHolder(defaultImpl)); } /** * Create new instance of class implementing SPI. * * @param The SPI type * @param spiClass Service Provider Interface Class. * @param propertiesFileName Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * @param defaultImpl Default implementation. * @return Instance of a class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public T newInstance(Class spiClass, String propertiesFileName, String defaultImpl) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { return newInstance(getClassLoaders(spiClass), new SPInterface(spiClass), new PropertiesHolder(propertiesFileName), new DefaultClassHolder(defaultImpl)); } /** * Create new instance of class implementing SPI. * * @param The SPI type * @param loaders The class loaders holder * @param spi Service Provider Interface Class. * @param properties Used to determine name of SPI implementation, * and passed to implementation.init() method if * implementation implements Service interface. * @param defaultImpl Default implementation. * @return Instance of a class implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public static T newInstance(ClassLoaders loaders, SPInterface spi, PropertiesHolder properties, DefaultClassHolder defaultImpl) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { return spi.newInstance(find(loaders, spi, properties, defaultImpl)); } /** *

Discover names of SPI implementation Classes from properties. * The names are the non-null values, in order, obtained from the following * resources: *

    *
  • ManagedProperty.getProperty(SPI.class.getName());
  • *
  • properties.getProperty(SPI.class.getName());
  • *
* * @param The SPI type * @param spi The SPI representation * @param properties Properties that may define the implementation * class name(s). * @return String[] Name of classes implementing the SPI. * @exception DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found. */ public static String[] discoverClassNames(SPInterface spi, Properties properties) { List names = new LinkedList(); String spiName = spi.getSPName(); String propertyName = spi.getPropertyName(); boolean includeAltProperty = !spiName.equals(propertyName); // Try the (managed) system property spiName String className = getManagedProperty(spiName); if (className != null) { names.add(className); } if (includeAltProperty) { // Try the (managed) system property propertyName className = getManagedProperty(propertyName); if (className != null) { names.add(className); } } if (properties != null) { // Try the properties parameter spiName className = properties.getProperty(spiName); if (className != null) { names.add(className); } if (includeAltProperty) { // Try the properties parameter propertyName className = properties.getProperty(propertyName); if (className != null) { names.add(className); } } } String[] results = new String[names.size()]; names.toArray(results); return results; } /** * Load the class whose name is given by the value of a (Managed) * System Property. * * @param propertyName the name of the system property whose value is * the name of the class to load. * @return The managed property value * @see ManagedProperties */ public static String getManagedProperty(String propertyName) { String value; try { value = ManagedProperties.getProperty(propertyName); } catch (SecurityException e) { value = null; } return value; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/ManagedProperties.java0000644000175000017500000003370311547002043031552 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Properties; import org.apache.commons.discovery.jdk.JDKHooks; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** *

This class may disappear in the future, or be moved to another project.. *

* *

Extend the concept of System properties to a hierarchical scheme * based around class loaders. System properties are global in nature, * so using them easily violates sound architectural and design principles * for maintaining separation between components and runtime environments. * Nevertheless, there is a need for properties broader in scope than * class or class instance scope. *

* *

This class is one solution. *

* *

Manage properties according to a secure * scheme similar to that used by classloaders: *

    *
  • ClassLoaders are organized in a tree hierarchy.
  • *
  • each ClassLoader has a reference * to a parent ClassLoader.
  • *
  • the root of the tree is the bootstrap ClassLoaderer.
  • *
  • the youngest decendent is the thread context class loader.
  • *
  • properties are bound to a ClassLoader instance *
      *
    • non-default properties bound to a parent ClassLoader * instance take precedence over all properties of the same name bound * to any decendent. * Just to confuse the issue, this is the default case.
    • *
    • default properties bound to a parent ClassLoader * instance may be overriden by (default or non-default) properties of * the same name bound to any decendent. *
    • *
    *
  • *
  • System properties take precedence over all other properties
  • *
*

* *

This is not a perfect solution, as it is possible that * different ClassLoaders load different instances of * ScopedProperties. The 'higher' this class is loaded * within the ClassLoader hierarchy, the more usefull * it will be. *

*/ public class ManagedProperties { private static Log log = LogFactory.getLog(ManagedProperties.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * Cache of Properties, keyed by (thread-context) class loaders. * Use HashMap because it allows 'null' keys, which * allows us to account for the (null) bootstrap classloader. */ private static final Map> propertiesCache = new HashMap>(); /** * Get value for property bound to the current thread context class loader. * * @param propertyName property name. * @return property value if found, otherwise default. */ public static String getProperty(String propertyName) { return getProperty(getThreadContextClassLoader(), propertyName); } /** * Get value for property bound to the current thread context class loader. * If not found, then return default. * * @param propertyName property name. * @param dephault default value. * @return property value if found, otherwise default. */ public static String getProperty(String propertyName, String dephault) { return getProperty(getThreadContextClassLoader(), propertyName, dephault); } /** * Get value for property bound to the class loader. * * @param classLoader The classloader used to load resources. * @param propertyName property name. * @return property value if found, otherwise default. */ public static String getProperty(ClassLoader classLoader, String propertyName) { String value = JDKHooks.getJDKHooks().getSystemProperty(propertyName); if (value == null) { Value val = getValueProperty(classLoader, propertyName); if (val != null) { value = val.value; } } else if (log.isDebugEnabled()) { log.debug("found System property '" + propertyName + "'" + " with value '" + value + "'."); } return value; } /** * Get value for property bound to the class loader. * If not found, then return default. * * @param classLoader The classloader used to load resources. * @param propertyName property name. * @param dephault default value. * @return property value if found, otherwise default. */ public static String getProperty(ClassLoader classLoader, String propertyName, String dephault) { String value = getProperty(classLoader, propertyName); return (value == null) ? dephault : value; } /** * Set value for property bound to the current thread context class loader. * @param propertyName property name * @param value property value (non-default) If null, remove the property. */ public static void setProperty(String propertyName, String value) { setProperty(propertyName, value, false); } /** * Set value for property bound to the current thread context class loader. * @param propertyName property name * @param value property value. If null, remove the property. * @param isDefault determines if property is default or not. * A non-default property cannot be overriden. * A default property can be overriden by a property * (default or non-default) of the same name bound to * a decendent class loader. */ public static void setProperty(String propertyName, String value, boolean isDefault) { if (propertyName != null) { synchronized (propertiesCache) { ClassLoader classLoader = getThreadContextClassLoader(); Map properties = propertiesCache.get(classLoader); if (value == null) { if (properties != null) { properties.remove(propertyName); } } else { if (properties == null) { properties = new HashMap(); propertiesCache.put(classLoader, properties); } properties.put(propertyName, new Value(value, isDefault)); } } } } /** * Set property values for Properties bound to the * current thread context class loader. * * @param newProperties name/value pairs to be bound */ public static void setProperties(Map newProperties) { setProperties(newProperties, false); } /** * Set property values for Properties bound to the * current thread context class loader. * * @param newProperties name/value pairs to be bound * @param isDefault determines if properties are default or not. * A non-default property cannot be overriden. * A default property can be overriden by a property * (default or non-default) of the same name bound to * a decendent class loader. */ public static void setProperties(Map newProperties, boolean isDefault) { /** * Each entry must be mapped to a Property. * 'setProperty' does this for us. */ for (Map.Entry entry : newProperties.entrySet()) { setProperty( String.valueOf(entry.getKey()), String.valueOf(entry.getValue()), isDefault); } } /** * Return list of all property names. This is an expensive * operation: ON EACH CALL it walks through all property lists * associated with the current context class loader upto * and including the bootstrap class loader. * * @return The list of all property names */ public static Enumeration propertyNames() { Map allProps = new Hashtable(); ClassLoader classLoader = getThreadContextClassLoader(); /** * Order doesn't matter, we are only going to use * the set of all keys... */ while (true) { Map properties = null; synchronized (propertiesCache) { properties = propertiesCache.get(classLoader); } if (properties != null) { allProps.putAll(properties); } if (classLoader == null) { break; } classLoader = getParent(classLoader); } return Collections.enumeration(allProps.keySet()); } /** * This is an expensive operation. * ON EACH CALL it walks through all property lists * associated with the current context class loader upto * and including the bootstrap class loader. * * @return Returns a java.util.Properties instance * that is equivalent to the current state of the scoped * properties, in that getProperty() will return the same value. * However, this is a copy, so setProperty on the * returned value will not effect the scoped properties. */ public static Properties getProperties() { Properties p = new Properties(); Enumeration names = propertyNames(); while (names.hasMoreElements()) { String name = names.nextElement(); p.put(name, getProperty(name)); } return p; } /***************** INTERNAL IMPLEMENTATION *****************/ private static class Value { final String value; final boolean isDefault; /** * Creates a new Value instance with string value and * the flag to mark is default value or not. * * @param value String representation of this value * @param isDefault The default flag */ Value(String value, boolean isDefault) { this.value = value; this.isDefault = isDefault; } } /** * Get value for properties bound to the class loader. * Explore up the tree first, as higher-level class * loaders take precedence over lower-level class loaders. * * * @param classLoader The class loader as key * @param propertyName The property name to lookup * @return The Value associated to the input class loader and property name */ private static final Value getValueProperty(ClassLoader classLoader, String propertyName) { Value value = null; if (propertyName != null) { /** * If classLoader isn't bootstrap loader (==null), * then get up-tree value. */ if (classLoader != null) { value = getValueProperty(getParent(classLoader), propertyName); } if (value == null || value.isDefault) { synchronized (propertiesCache) { Map properties = propertiesCache.get(classLoader); if (properties != null) { Value altValue = properties.get(propertyName); // set value only if override exists.. // otherwise pass default (or null) on.. if (altValue != null) { value = altValue; if (log.isDebugEnabled()) { log.debug("found Managed property '" + propertyName + "'" + " with value '" + value + "'" + " bound to classloader " + classLoader + "."); } } } } } } return value; } /** * Returns the thread context class loader. * * @return The thread context class loader */ private static final ClassLoader getThreadContextClassLoader() { return JDKHooks.getJDKHooks().getThreadContextClassLoader(); } /** * Return the parent class loader of the given class loader. * * @param classLoader The class loader from wich the parent has to be extracted * @return The parent class loader of the given class loader */ private static final ClassLoader getParent(final ClassLoader classLoader) { return AccessController.doPrivileged(new PrivilegedAction() { public ClassLoader run() { try { return classLoader.getParent(); } catch (SecurityException se){ return null; } } }); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/PropertiesHolder.java0000644000175000017500000000531611546615411031442 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.util.Properties; import org.apache.commons.discovery.resource.ClassLoaders; /** * Holder for a default class. * * Class may be specified by name (String) or class (Class). * Using the holder complicates the users job, but minimized # of API's. */ public class PropertiesHolder { private Properties properties; private final String propertiesFileName; /** * Creates a new {@code PropertiesHolder} instance given an * already load {@code Properties} set. * * @param properties The already load {@code Properties} set */ public PropertiesHolder(Properties properties) { this.properties = properties; this.propertiesFileName = null; } /** * Creates a new {@code PropertiesHolder} instance given a * property file name. * * @param propertiesFileName The property file name */ public PropertiesHolder(String propertiesFileName) { this.properties = null; this.propertiesFileName = propertiesFileName; } /** * Returns the {@code Properties} instance, loaded if necessary from {@code propertiesFileName}. * * @param spi Optional SPI (may be null). * If provided, an attempt is made to load the * property file as-per Class.getResource(). * * @param loaders Used only if properties need to be loaded. * * @return The {@code Properties}, loaded if necessary. */ public Properties getProperties(SPInterface spi, ClassLoaders loaders) { if (properties == null) { properties = ResourceUtils.loadProperties(spi.getSPClass(), getPropertiesFileName(), loaders); } return properties; } /** * Returns the property file name * * @return The property file name */ public String getPropertiesFileName() { return propertiesFileName; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/EnvironmentCache.java0000644000175000017500000001061111546617175031403 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.util.HashMap; import java.util.Map; import org.apache.commons.discovery.jdk.JDKHooks; /** * Cache by a 'key' unique to the environment: * * - ClassLoader::groupContext::Object Cache * Cache : HashMap * Key : Thread Context Class Loader (ClassLoader) * Value : groupContext::SPI Cache (HashMap) * * //- groupContext::Object Cache * // Cache : HashMap * // Key : groupContext (String) * // Value : Object * * When we 'release', it is expected that the caller of the 'release' * have the same thread context class loader... as that will be used * to identify cached entries to be released. */ public class EnvironmentCache { /** * Allows null key, important as default groupContext is null. * * We will manage synchronization directly, so all caches are implemented * as HashMap (unsynchronized). */ private static final Map> root_cache = new HashMap>(); /** * Initial hash size for SPI's, default just seem TO big today.. */ public static final int smallHashSize = 13; /** * Get object keyed by classLoader. * * @param classLoader The class loader key * @return The SPI name/instance cache */ public static synchronized Map get(ClassLoader classLoader) { /* * 'null' (bootstrap/system class loader) thread context class loader * is ok... Until we learn otherwise. */ return root_cache.get(classLoader); } /** * Put service keyed by spi & classLoader. * * @param classLoader The class loader key * @param spis The SPI name/instance cache */ public static synchronized void put(ClassLoader classLoader, Map spis) { /* * 'null' (bootstrap/system class loader) thread context class loader * is ok... Until we learn otherwise. */ if (spis != null) { root_cache.put(classLoader, spis); } } /********************** CACHE-MANAGEMENT SUPPORT **********************/ /** * Release all internal references to previously created service * instances associated with the current thread context class loader. * The release() method is called for service instances that * implement the Service interface. * * This is useful in environments like servlet containers, * which implement application reloading by throwing away a ClassLoader. * Dangling references to objects in that class loader would prevent * garbage collection. */ public static synchronized void release() { /* * 'null' (bootstrap/system class loader) thread context class loader * is ok... Until we learn otherwise. */ root_cache.remove(JDKHooks.getJDKHooks().getThreadContextClassLoader()); } /** * Release any internal references to a previously created service * instance associated with the current thread context class loader. * If the SPI instance implements Service, then call * release(). * * @param classLoader The class loader key */ public static synchronized void release(ClassLoader classLoader) { /* * 'null' (bootstrap/system class loader) thread context class loader * is ok... Until we learn otherwise. */ root_cache.remove(classLoader); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/SPInterface.java0000644000175000017500000002147011550133124030301 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.lang.reflect.InvocationTargetException; import org.apache.commons.discovery.DiscoveryException; /** * Represents a Service Programming Interface (spi). * - SPI's name * - SPI's (provider) class * - SPI's (alternate) override property name * * In addition, while there are many cases where this is NOT * usefull, for those in which it is: * * - expected constructor argument types and parameters values. * * @param The SPI type */ public class SPInterface { /** * Construct object representing Class {@code provider}. * * @param The SPI type * @param provider The SPI class * @return A new object representing Class {@code provider} * @since 0.5 */ public static SPInterface newSPInterface(Class provider) { return newSPInterface(provider, provider.getName()); } /** * Construct object representing Class {@code provider}. * * @param The SPI type * @param provider The SPI class * @param propertyName when looking for the name of a class implementing * the provider class, a discovery strategy may involve looking for * (system or other) properties having either the name of the class * (provider) or the propertyName. * @return A new object representing Class {@code provider} * @since 0.5 */ public static SPInterface newSPInterface(Class provider, String propertyName) { return new SPInterface(provider, propertyName); } /** * Construct object representing Class {@code provider}. * * @param The SPI type * @param provider The SPI class * @param constructorParamClasses classes representing the * constructor argument types * @param constructorParams objects representing the * constructor arguments * @return A new object representing Class {@code provider} * @since 0.5 */ public static SPInterface newSPInterface(Class provider, Class constructorParamClasses[], Object constructorParams[]) { return newSPInterface(provider, provider.getName(), constructorParamClasses, constructorParams); } /** * Construct object representing Class {@code provider}. * * @param The SPI type * @param provider The SPI class * @param propertyName when looking for the name of a class implementing * the provider class, a discovery strategy may involve looking for * (system or other) properties having either the name of the class * (provider) or the propertyName. * @param constructorParamClasses classes representing the * constructor argument types * @param constructorParams objects representing the * constructor arguments * @return A new object representing Class {@code provider} * @since 0.5 */ public static SPInterface newSPInterface(Class provider, String propertyName, Class constructorParamClasses[], Object constructorParams[]) { return new SPInterface(provider, propertyName, constructorParamClasses, constructorParams); } /** * The service programming interface: intended to be * an interface or abstract class, but not limited * to those two. */ private final Class spi; /** * The property name to be used for finding the name of * the SPI implementation class. */ private final String propertyName; private final Class paramClasses[]; private final Object params[]; /** * Construct object representing Class provider. * * @param provider The SPI class */ public SPInterface(Class provider) { this(provider, provider.getName()); } /** * Construct object representing Class provider. * * @param spi The SPI class * * @param propertyName when looking for the name of a class implementing * the provider class, a discovery strategy may involve looking for * (system or other) properties having either the name of the class * (provider) or the propertyName. */ public SPInterface(Class spi, String propertyName) { this.spi = spi; this.propertyName = propertyName; this.paramClasses = null; this.params = null; } /** * Construct object representing Class provider. * * @param provider The SPI class * * @param constructorParamClasses classes representing the * constructor argument types. * * @param constructorParams objects representing the * constructor arguments. */ public SPInterface(Class provider, Class constructorParamClasses[], Object constructorParams[]) { this(provider, provider.getName(), constructorParamClasses, constructorParams); } /** * Construct object representing Class provider. * * @param spi The SPI class * * @param propertyName when looking for the name of a class implementing * the provider class, a discovery strategy may involve looking for * (system or other) properties having either the name of the class * (provider) or the propertyName. * * @param constructorParamClasses classes representing the * constructor argument types. * * @param constructorParams objects representing the * constructor arguments. */ public SPInterface(Class spi, String propertyName, Class constructorParamClasses[], Object constructorParams[]) { this.spi = spi; this.propertyName = propertyName; this.paramClasses = constructorParamClasses; this.params = constructorParams; } /** * Returns the SPI class name. * * @return The SPI class name */ public String getSPName() { return spi.getName(); } /** * Returns the SPI class. * * @return The SPI class */ public Class getSPClass() { return spi; } /** * Returns the property name to be used for finding * the name of the SPI implementation class. * * @return The property name to be used for finding * the name of the SPI implementation class */ public String getPropertyName() { return propertyName; } /** * Creates a new instance of the given SPI class. * * @param Any type extends T * @param impl The SPI class has to be instantiated * @return A new instance of the given SPI class * @throws DiscoveryException if the class implementing * the SPI cannot be found, cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public S newInstance(Class impl) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { verifyAncestory(impl); return ClassUtils.newInstance(impl, paramClasses, params); } /** * Verifies the given SPI implementation is a SPI specialization. * * @param Any type extends T * @param impl The SPI instantance */ public void verifyAncestory(Class impl) { ClassUtils.verifyAncestory(spi, impl); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/Service.java0000644000175000017500000001102111550164115027531 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.util.Enumeration; import java.util.NoSuchElementException; import org.apache.commons.discovery.ResourceClass; import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.discovery.resource.classes.DiscoverClasses; import org.apache.commons.discovery.resource.names.DiscoverServiceNames; /** * [this was ServiceDiscovery12... the 1.1 versus 1.2 issue * has been abstracted to org.apache.commons.discover.jdk.JDKHooks] * *

Implement the JDK1.3 'Service Provider' specification. * ( http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html ) *

* * This class supports any VM, including JDK1.1, via * org.apache.commons.discover.jdk.JDKHooks. * * The caller will first configure the discoverer by adding ( in the desired * order ) all the places to look for the META-INF/services. Currently * we support loaders. * * The findResources() method will check every loader. */ public class Service { /** * Construct a new service discoverer */ protected Service() { } /** * as described in * sun/jdk1.3.1/docs/guide/jar/jar.html#Service Provider, * Except this uses Enumeration * instead of Interator. * * @param Service Provider Interface type * @param Any type extends the SPI type * @param spiClass Service Provider Interface Class * @return Enumeration of class instances ({@code S}) */ public static Enumeration providers(Class spiClass) { return providers(new SPInterface(spiClass), null); } /** * This version lets you specify constructor arguments.. * * @param Service Provider Interface type * @param Any type extends the SPI type * @param spi SPI to look for and load. * @param loaders loaders to use in search. * If null then use ClassLoaders.getAppLoaders(). * @return Enumeration of class instances ({@code S}) */ public static Enumeration providers(final SPInterface spi, ClassLoaders loaders) { if (loaders == null) { loaders = ClassLoaders.getAppLoaders(spi.getSPClass(), Service.class, true); } ResourceNameIterator servicesIter = (new DiscoverServiceNames(loaders)).findResourceNames(spi.getSPName()); final ResourceClassIterator services = (new DiscoverClasses(loaders)).findResourceClasses(servicesIter); return new Enumeration() { private S object = getNextClassInstance(); public boolean hasMoreElements() { return object != null; } public S nextElement() { if (object == null) { throw new NoSuchElementException(); } S obj = object; object = getNextClassInstance(); return obj; } private S getNextClassInstance() { while (services.hasNext()) { ResourceClass info = services.nextResourceClass(); try { return spi.newInstance(info.loadClass()); } catch (Exception e) { // ignore } catch (LinkageError le) { // ignore } } return null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/ClassUtils.java0000644000175000017500000001616011547423466030245 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.commons.discovery.DiscoveryException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Various utilities to interact with {@code Class} types. */ public class ClassUtils { private static Log log = LogFactory.getLog(ClassUtils.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * Get package name. * Not all class loaders 'keep' package information, * in which case Class.getPackage() returns null. * This means that calling Class.getPackage().getName() * is unreliable at best. * * @param clazz The class from which the package has to be extracted * @return The string representation of the input class package */ public static String getPackageName(Class clazz) { Package clazzPackage = clazz.getPackage(); String packageName; if (clazzPackage != null) { packageName = clazzPackage.getName(); } else { String clazzName = clazz.getName(); packageName = clazzName.substring(0, clazzName.lastIndexOf('.')); } return packageName; } /** * Looks for {@code public static returnType methodName(paramTypes)}. * * @param clazz The class where looking for the method * @param returnType The method return type * @param methodName The method name * @param paramTypes The method arguments types * @return Method {@code public static returnType methodName(paramTypes)}, * if found to be directly implemented by clazz. */ public static Method findPublicStaticMethod(Class clazz, Class returnType, String methodName, Class[] paramTypes) { boolean problem = false; Method method = null; // verify '()' is directly in class. try { method = clazz.getDeclaredMethod(methodName, paramTypes); } catch(NoSuchMethodException e) { problem = true; log.debug("Class " + clazz.getName() + ": missing method '" + methodName + "(...)", e); } // verify 'public static ' if (!problem && !(Modifier.isPublic(method.getModifiers()) && Modifier.isStatic(method.getModifiers()) && method.getReturnType() == returnType)) { if (log.isDebugEnabled()) { if (!Modifier.isPublic(method.getModifiers())) { log.debug(methodName + "() is not public"); } if (!Modifier.isStatic(method.getModifiers())) { log.debug(methodName + "() is not static"); } if (method.getReturnType() != returnType) { log.debug("Method returns: " + method.getReturnType().getName() + "@@" + method.getReturnType().getClassLoader()); log.debug("Should return: " + returnType.getName() + "@@" + returnType.getClassLoader()); } } problem = true; method = null; } return method; } /** * Creates a new instance of the input class using the following policy: * *
    *
  • if paramClasses or params is null, * the default constructor will be used;
  • *
  • the public constructor with paramClasses arguments type, * with params as arguments value, will be used.
  • *
* * @param The class type has to be instantiated * @param impl The class has to be instantiated * @param paramClasses The constructor arguments types (can be {@code null}) * @param params The constructor arguments values (can be {@code null}) * @return A new class instance * @throws DiscoveryException if the class implementing * the SPI cannot be found, cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI * @throws InstantiationException see {@link Class#newInstance()} * @throws IllegalAccessException see {@link Class#newInstance()} * @throws NoSuchMethodException see {@link Class#newInstance()} * @throws InvocationTargetException see {@link Class#newInstance()} */ public static T newInstance(Class impl, Class paramClasses[], Object params[]) throws DiscoveryException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { if (paramClasses == null || params == null) { return impl.newInstance(); } Constructor constructor = impl.getConstructor(paramClasses); return constructor.newInstance(params); } /** * Throws exception if {@code impl} does not * implement or extend the SPI. * * @param spi The SPI type * @param impl The class has to be verified is a SPI implementation/extension * @throws DiscoveryException if the input implementation class is not an SPI implementation */ public static void verifyAncestory(Class spi, Class impl) throws DiscoveryException { if (spi == null) { throw new DiscoveryException("No interface defined!"); } if (impl == null) { throw new DiscoveryException("No implementation defined for " + spi.getName()); } if (!spi.isAssignableFrom(impl)) { throw new DiscoveryException("Class " + impl.getName() + " does not implement " + spi.getName()); } } } commons-discovery-0.5/src/java/org/apache/commons/discovery/tools/ResourceUtils.java0000644000175000017500000001365211547423466030772 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.tools; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.apache.commons.discovery.DiscoveryException; import org.apache.commons.discovery.Resource; import org.apache.commons.discovery.ResourceIterator; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.discovery.resource.DiscoverResources; /** * Mechanisms to locate and load a class. * * The load methods locate a class only. * The find methods locate a class and verify that the * class implements an given interface or extends a given class. */ public class ResourceUtils { /** * Get package name. * * Not all class loaders 'keep' package information, * in which case Class.getPackage() returns null. * This means that calling Class.getPackage().getName() * is unreliable at best. * * @param clazz The class from which the package has to be extracted * @return The string representation of the input class package */ public static String getPackageName(Class clazz) { Package clazzPackage = clazz.getPackage(); String packageName; if (clazzPackage != null) { packageName = clazzPackage.getName(); } else { String clazzName = clazz.getName(); packageName = new String(clazzName.toCharArray(), 0, clazzName.lastIndexOf('.')); } return packageName; } /** * Load the resource resourceName. * * Try each classloader in succession, * until first succeeds, or all fail. * If all fail and resouceName is not absolute * (doesn't start with '/' character), then retry with * packageName/resourceName after changing all * '.' to '/'. * * @param spi The SPI type * @param resourceName The name of the resource to load. * @param loaders the class loaders holder * @return The discovered {@link Resource} instance * @throws DiscoveryException if the class implementing * the SPI cannot be found, cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI */ public static Resource getResource(Class spi, String resourceName, ClassLoaders loaders) throws DiscoveryException { DiscoverResources explorer = new DiscoverResources(loaders); ResourceIterator resources = explorer.findResources(resourceName); if (spi != null && !resources.hasNext() && resourceName.charAt(0) != '/') { /** * If we didn't find the resource, and if the resourceName * isn't an 'absolute' path name, then qualify with * package name of the spi. */ resourceName = getPackageName(spi).replace('.','/') + "/" + resourceName; resources = explorer.findResources(resourceName); } return resources.hasNext() ? resources.nextResource() : null; } /** * Load named property file, optionally qualified by spi's package name * as per Class.getResource. * * A property file is loaded using the following sequence of class loaders: *
    *
  • Thread Context Class Loader
  • *
  • DiscoverSingleton's Caller's Class Loader
  • *
  • SPI's Class Loader
  • *
  • DiscoverSingleton's (this class) Class Loader
  • *
  • System Class Loader
  • *
* * @param spi The SPI type * @param propertiesFileName The property file name. * @param classLoaders The class loaders holder * @return The loaded named property file, in {@code Properties} format * @throws DiscoveryException Thrown if the name of a class implementing * the SPI cannot be found, if the class cannot be loaded and * instantiated, or if the resulting class does not implement * (or extend) the SPI. */ public static Properties loadProperties(Class spi, String propertiesFileName, ClassLoaders classLoaders) throws DiscoveryException { Properties properties = null; if (propertiesFileName != null) { try { Resource resource = getResource(spi, propertiesFileName, classLoaders); if (resource != null) { InputStream stream = resource.getResourceAsStream(); if (stream != null) { properties = new Properties(); try { properties.load(stream); } finally { stream.close(); } } } } catch (IOException e) { // ignore } catch (SecurityException e) { // ignore } } return properties; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceIterator.java0000644000175000017500000000253311546563027030314 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * Iterator over discovered {@link Resource}. */ public abstract class ResourceIterator implements ResourceNameIterator { /** * Returns the next {@link Resource} in the iteration. * * @return The next resource in the iteration */ public abstract Resource nextResource(); /** * Returns the next resource name in the iteration. * * @return The next resource name in the iteration */ public String nextResourceName() { return nextResource().getName(); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceClassDiscover.java0000644000175000017500000000277211546563027031274 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * SPI Discovery. * * @param The SPI type */ public interface ResourceClassDiscover extends ResourceDiscover { /** * Locate class resources that are bound to {@code className}. * * @param className The class name has to be located * @return The iterator over the located classes */ ResourceClassIterator findResourceClasses(String className); /** * Locate class resources that are bound to {@code resourceNames}. * * @param classNames The classes name has to be located * @return The iterator over the located classes */ ResourceClassIterator findResourceClasses(ResourceNameIterator classNames); } commons-discovery-0.5/src/java/org/apache/commons/discovery/jdk/0000755000175000017500000000000011643422201024677 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/jdk/package-info.java0000644000175000017500000000160511546710126030100 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Different JDK hookers style implementation. */ package org.apache.commons.discovery.jdk; commons-discovery-0.5/src/java/org/apache/commons/discovery/jdk/JDK11Hooks.java0000644000175000017500000001067111546640301027332 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.jdk; import java.io.IOException; import java.net.URL; import java.util.Enumeration; /** * JDK 1.1 Style Hooks implementation. */ public class JDK11Hooks extends JDKHooks { private static final ClassLoader systemClassLoader = new PsuedoSystemClassLoader(); /** * {@inheritDoc} */ @Override public String getSystemProperty(final String propName) { return System.getProperty(propName); } /** * {@inheritDoc} */ @Override public ClassLoader getThreadContextClassLoader() { return null; } /** * {@inheritDoc} */ @Override public ClassLoader getSystemClassLoader() { return systemClassLoader; } /** * {@inheritDoc} */ @Override public Enumeration getResources(ClassLoader loader, String resourceName) throws IOException { /* * The simple answer is/was: * return loader.getResources(resourceName); * * However, some classloaders overload the behavior of getResource * (loadClass, etc) such that the order of returned results changes * from normally expected behavior. * * Example: locate classes/resources from child ClassLoaders first, * parents last (in some J2EE environs). * * The resource returned by getResource() should be the same as the * first resource returned by getResources(). Unfortunately, this * is not, and cannot be: getResources() is 'final' in the current * JDK's (1.2, 1.3, 1.4). * * To address this, the implementation of this method will * return an Enumeration such that the first element is the * results of getResource, and all trailing elements are * from getResources. On each iteration, we check so see * if the resource (from getResources) matches the first resource, * and eliminate the redundent element. */ final URL first = loader.getResource(resourceName); final Enumeration rest = loader.getResources(resourceName); return new Enumeration() { private boolean firstDone = (first == null); private URL next = getNext(); public URL nextElement() { URL o = next; next = getNext(); return o; } public boolean hasMoreElements() { return next != null; } private URL getNext() { URL n; if (!firstDone) { /* * First time through, use results of getReference() * if they were non-null. */ firstDone = true; n = first; } else { /* * Subsequent times through, * use results of getReferences() * but take out anything that matches 'first'. * * Iterate through list until we find one that * doesn't match 'first'. */ n = null; while (rest.hasMoreElements() && n == null) { n = rest.nextElement(); if (first != null && n != null && n.equals(first)) { n = null; } } } return n; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/jdk/PsuedoSystemClassLoader.java0000644000175000017500000000316411546635274032351 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.jdk; import java.io.InputStream; import java.net.URL; /** * JDK 1.1.x compatible? * There is no direct way to get the system class loader * in 1.1.x, but this should be a good work around... */ class PsuedoSystemClassLoader extends ClassLoader { /** * {@inheritDoc} */ @Override protected Class loadClass(String className, @SuppressWarnings("unused") boolean resolve) throws ClassNotFoundException { return findSystemClass(className); } /** * {@inheritDoc} */ @Override public URL getResource(String resName) { return getSystemResource(resName); } /** * {@inheritDoc} */ @Override public InputStream getResourceAsStream(String resName) { return getSystemResourceAsStream(resName); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/jdk/JDK12Hooks.java0000644000175000017500000001776111547002043027336 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.jdk; import java.io.IOException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Enumeration; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * JDK 1.2 Style Hooks implementation. */ public class JDK12Hooks extends JDKHooks { /** * Logger */ private static Log log = LogFactory.getLog(JDK12Hooks.class); private static final ClassLoader systemClassLoader = findSystemClassLoader(); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * {@inheritDoc} */ @Override public String getSystemProperty(final String propName) { return AccessController.doPrivileged(new PrivilegedAction() { public String run() { try { return System.getProperty(propName); } catch (SecurityException se){ return null; } } }); } /** * {@inheritDoc} */ @Override public ClassLoader getThreadContextClassLoader() { ClassLoader classLoader; try { classLoader = Thread.currentThread().getContextClassLoader(); } catch (SecurityException e) { /* * SecurityException is thrown when * a) the context class loader isn't an ancestor of the * calling class's class loader, or * b) if security permissions are restricted. * * For (a), ignore and keep going. We cannot help but also * ignore (b) with the logic below, but other calls elsewhere * (to obtain a class loader) will re-trigger this exception * where we can make a distinction. */ classLoader = null; // ignore } // Return the selected class loader return classLoader; } /** * {@inheritDoc} */ @Override public ClassLoader getSystemClassLoader() { return systemClassLoader; } /** * {@inheritDoc} */ @Override public Enumeration getResources(ClassLoader loader, String resourceName) throws IOException { /* * The simple answer is/was: * return loader.getResources(resourceName); * * However, some classloaders overload the behavior of getResource * (loadClass, etc) such that the order of returned results changes * from normally expected behavior. * * Example: locate classes/resources from child ClassLoaders first, * parents last (in some J2EE environs). * * The resource returned by getResource() should be the same as the * first resource returned by getResources(). Unfortunately, this * is not, and cannot be: getResources() is 'final' in the current * JDK's (1.2, 1.3, 1.4). * * To address this, the implementation of this method will * return an Enumeration such that the first element is the * results of getResource, and all trailing elements are * from getResources. On each iteration, we check so see * if the resource (from getResources) matches the first resource, * and eliminate the redundent element. */ final URL first = loader.getResource(resourceName); // XXX: Trying to avoid JBoss UnifiedClassLoader problem Enumeration resources; if (first == null) { if (log.isDebugEnabled()) { log.debug("Could not find resource: " + resourceName); } List emptyURL = Collections.emptyList(); resources = Collections.enumeration(emptyURL); } else { try { resources = loader.getResources(resourceName); } catch (RuntimeException ex) { log.error("Exception occured during attept to get " + resourceName + " from " + first, ex); List emptyURL = Collections.emptyList(); resources = Collections.enumeration(emptyURL); } resources = getResourcesFromUrl(first, resources); } return resources; } /** * Enumerates resources URL. * * @param first The first URL in the enumeration sequence * @param rest The URL enumeration * @return A new resources URL enumeration */ private static Enumeration getResourcesFromUrl(final URL first, final Enumeration rest) { return new Enumeration() { private boolean firstDone = (first == null); private URL next = getNext(); public URL nextElement() { URL o = next; next = getNext(); return o; } public boolean hasMoreElements() { return next != null; } private URL getNext() { URL n; if (!firstDone) { /* * First time through, use results of getReference() * if they were non-null. */ firstDone = true; n = first; } else { /* * Subsequent times through, * use results of getReferences() * but take out anything that matches 'first'. * * Iterate through list until we find one that * doesn't match 'first'. */ n = null; while (rest.hasMoreElements() && n == null) { n = rest.nextElement(); if (first != null && n != null && n.equals(first)) { n = null; } } } return n; } }; } /** * Find the System {@code ClassLoader}. * * @return The System {@code ClassLoader} */ static private ClassLoader findSystemClassLoader() { ClassLoader classLoader; try { classLoader = ClassLoader.getSystemClassLoader(); } catch (SecurityException e) { /* * Ignore and keep going. */ classLoader = null; } if (classLoader == null) { SecurityManager security = System.getSecurityManager(); if (security != null) { try { security.checkCreateClassLoader(); classLoader = new PsuedoSystemClassLoader(); } catch (SecurityException se){ } } } // Return the selected class loader return classLoader; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/jdk/JDKHooks.java0000644000175000017500000000533411547423466027204 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.jdk; import java.io.IOException; import java.net.URL; import java.util.Enumeration; /** * JDK Hooks to extract properties/resources. */ public abstract class JDKHooks { private static final JDKHooks jdkHooks; static { jdkHooks = new JDK12Hooks(); } /** * Hidden constructor, this class can't be directly instantiated. */ protected JDKHooks() { } /** * Return singleton object representing JVM hooks/tools. * * TODO: add logic to detect JDK level. * * @return The detected {@code JDKHooks} */ public static final JDKHooks getJDKHooks() { return jdkHooks; } /** * Get the system property * * @param propName name of the property * @return value of the property */ public abstract String getSystemProperty(final String propName); /** * The thread context class loader is available for JDK 1.2 * or later, if certain security conditions are met. * * @return The thread context class loader, if available. * Otherwise return null. */ public abstract ClassLoader getThreadContextClassLoader(); /** * The system class loader is available for JDK 1.2 * or later, if certain security conditions are met. * * @return The system class loader, if available. * Otherwise return null. */ public abstract ClassLoader getSystemClassLoader(); /** * Resolve resource with given names and make them available in * the returned iterator. * * @param loader The class loader used to resolve resources * @param resourceName The resource name to resolve * @return The iterator over the URL resolved resources * @throws IOException if any error occurs while loading the resource */ public abstract Enumeration getResources(ClassLoader loader, String resourceName) throws IOException; } commons-discovery-0.5/src/java/org/apache/commons/discovery/ant/0000755000175000017500000000000011643422201024711 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/ant/ServiceDiscoveryTask.java0000644000175000017500000000541711546634120031705 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.ant; import java.util.LinkedList; import java.util.List; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.jdk.JDKHooks; import org.apache.commons.discovery.resource.DiscoverResources; /** * Small ant task that will use discovery to locate a particular impl. * and display all values. * * You can execute this and save it with an id, then other classes can use it. */ public class ServiceDiscoveryTask { String name; int debug=0; String[] drivers = null; /** * Sets the service name has to be discovered. * * @param name The service name has to be discovered. */ public void setServiceName(String name) { this.name=name; } /** * Sets the debug level. * * @param i The debug level */ public void setDebug(int i) { this.debug=i; } /** * Returns the discovered SPIs name. * * @return The discovered SPIs name */ public String[] getServiceInfo() { return drivers; } /** * Executes the Apache Ant task, discovering the set service name * * @throws Exception if any error occurs */ public void execute() throws Exception { System.out.printf("Discovering service '%s'...%n", name); DiscoverResources disc = new DiscoverResources(); disc.addClassLoader( JDKHooks.getJDKHooks().getThreadContextClassLoader() ); disc.addClassLoader( this.getClass().getClassLoader() ); ResourceNameIterator iterator = disc.findResources(name); List resources = new LinkedList(); while (iterator.hasNext()) { String resourceInfo = iterator.nextResourceName(); resources.add(resourceInfo); if (debug > 0) { System.out.printf("Found '%s'%n", resourceInfo); } } drivers = new String[resources.size()]; resources.toArray(drivers); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/ant/package-info.java0000644000175000017500000000161011546710126030106 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Apache Commons-Discovery tasks for Apache Ant. */ package org.apache.commons.discovery.ant; commons-discovery-0.5/src/java/org/apache/commons/discovery/DiscoveryException.java0000644000175000017500000000406711546563027030645 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * An exception that is thrown only if a suitable service * instance cannot be created by {@code ServiceFactory}. * * @version $Revision: 1088947 $ $Date: 2011-04-05 11:51:19 +0200 (mar. 05 avril 2011) $ */ public class DiscoveryException extends RuntimeException { /** * */ private static final long serialVersionUID = -2518293836976054070L; /** * Construct a new exception with null as its detail message. */ public DiscoveryException() { super(); } /** * Construct a new exception with the specified detail message. * * @param message The detail message */ public DiscoveryException(String message) { super(message); } /** * Construct a new exception with the specified cause and a derived * detail message. * * @param cause The underlying cause */ public DiscoveryException(Throwable cause) { super(cause); } /** * Construct a new exception with the specified detail message and cause. * * @param message The detail message * @param cause The underlying cause */ public DiscoveryException(String message, Throwable cause) { super(message, cause); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceClassIterator.java0000644000175000017500000000274111546563027031303 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * Iterator over discovered SPI type. * * @param The SPI type */ public abstract class ResourceClassIterator extends ResourceIterator { /** * Returns the next SPI Class in the iteration. * * @param Any type extends T * @return The next SPI Class in the iteration */ public abstract ResourceClass nextResourceClass(); /** * {@inheritDoc} */ @Override public Resource nextResource() { return nextResourceClass(); } /** * {@inheritDoc} */ @Override public String nextResourceName() { return nextResourceClass().getName(); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceDiscover.java0000644000175000017500000000300311546563027030272 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * Interface representing a mapping * from a set of source resource names * to a resultant set of resource. */ public interface ResourceDiscover extends ResourceNameDiscover { /** * Locate resources that are bound to {@code resourceName}. * * @param resourceName The resource has to be located * @return The bound resources iterator */ ResourceIterator findResources(String resourceName); /** * Locate resources that are bound to {@code resourceNames}. * * @param resourceNames The resource has to be located * @return The bound resources iterator */ ResourceIterator findResources(ResourceNameIterator resourceNames); } commons-discovery-0.5/src/java/org/apache/commons/discovery/Resource.java0000644000175000017500000000640711546563027026606 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.LinkedList; import java.util.List; /** * 'Resource' located by discovery. * Naming of methods becomes a real pain ('getClass()') * so I've patterned this after ClassLoader... * * I think it works well as it will give users a point-of-reference. */ public class Resource { protected final String name; protected final URL resource; protected final ClassLoader loader; /** * Create a new {@link Resource} instance. * * @param resourceName The resource name has to be located * @param resource The resource URL has to be located * @param loader The class loader used to locate the given resource */ public Resource(String resourceName, URL resource, ClassLoader loader) { this.name = resourceName; this.resource = resource; this.loader = loader; } /** * Get the value of resourceName. * @return value of resourceName. */ public String getName() { return name; } /** * Get the value of URL. * @return value of URL. */ public URL getResource() { return resource; } /** * Get the value of URL. * @return value of URL. */ public InputStream getResourceAsStream() { try { return resource.openStream(); } catch (IOException e) { return null; // ignore } } /** * Get the value of loader. * @return value of loader. */ public ClassLoader getClassLoader() { return loader ; } /** * {@inheritDoc} */ @Override public String toString() { return "Resource[" + getName() + ", " + getResource() + ", " + getClassLoader() + "]"; } /** * Returns an array containing all of the elements in this {@link ResourceIterator} in proper sequence. * * @param iterator The {@link ResourceIterator} containing the * @return An array containing the elements of the given {@link ResourceIterator} */ public static Resource[] toArray(ResourceIterator iterator) { List resourceList = new LinkedList(); while (iterator.hasNext()) { resourceList.add(iterator.nextResource()); } Resource[] resources = new Resource[resourceList.size()]; resourceList.toArray(resources); return resources; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/0000755000175000017500000000000011643422201025756 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/package-info.java0000644000175000017500000000157311546710126031163 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Resources discovery catalog. */ package org.apache.commons.discovery.resource; commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/classes/0000755000175000017500000000000011643422201027413 5ustar drazzibdrazzibcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/classes/package-info.java0000644000175000017500000000161311546710126032613 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Classes resources discovery catalog. */ package org.apache.commons.discovery.resource.classes; ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/classes/ResourceClassDiscoverImpl.javacommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/classes/ResourceClassDiscoverIm0000644000175000017500000001021311546704675034121 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.classes; import org.apache.commons.discovery.ResourceClass; import org.apache.commons.discovery.ResourceClassDiscover; import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.ResourceIterator; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.discovery.resource.ResourceDiscoverImpl; /** * Default {@link ResourceClassDiscover} implementation. * * @param The SPI type */ public abstract class ResourceClassDiscoverImpl extends ResourceDiscoverImpl implements ResourceClassDiscover { /** * Construct a new resource discoverer. */ public ResourceClassDiscoverImpl() { super(); } /** * Construct a new resource discoverer. * * @param classLoaders The class loaders holder */ public ResourceClassDiscoverImpl(ClassLoaders classLoaders) { super(classLoaders); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(String resourceName) { return findResourceClasses(resourceName); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames) { return findResourceClasses(resourceNames); } /** * {@inheritDoc} */ @Override public ResourceIterator findResources(String resourceName) { return findResourceClasses(resourceName); } /** * {@inheritDoc} */ @Override public ResourceIterator findResources(ResourceNameIterator resourceNames) { return findResourceClasses(resourceNames); } /** * Locate class resources that are bound to className. * * @param className The class name has to be located * @return The located resources iterator */ public abstract ResourceClassIterator findResourceClasses(String className); /** * Locate class resources that are bound to {@code resourceNames}. * * @param inputNames The resource name iterator * @return a new {@link ResourceClassIterator} over the given resource name iterator */ public ResourceClassIterator findResourceClasses(final ResourceNameIterator inputNames) { return new ResourceClassIterator() { private ResourceClassIterator classes = null; private ResourceClass resource = null; public boolean hasNext() { if (resource == null) { resource = getNextResource(); } return resource != null; } @Override public ResourceClass nextResourceClass() { ResourceClass rsrc = resource; resource = null; return rsrc; } private ResourceClass getNextResource() { while (inputNames.hasNext() && (classes == null || !classes.hasNext())) { classes = findResourceClasses(inputNames.nextResourceName()); } return (classes != null && classes.hasNext()) ? classes.nextResourceClass() : null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/classes/DiscoverClasses.java0000644000175000017500000001152611550170333033362 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.classes; import java.net.URL; import java.security.CodeSource; import java.util.HashSet; import java.util.Set; import org.apache.commons.discovery.ResourceClass; import org.apache.commons.discovery.ResourceClassDiscover; import org.apache.commons.discovery.ResourceClassIterator; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * The findResources() method will check every loader. * * @param The SPI type */ public class DiscoverClasses extends ResourceClassDiscoverImpl implements ResourceClassDiscover { private static Log log = LogFactory.getLog(DiscoverClasses.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * Construct a new resource discoverer */ public DiscoverClasses() { super(); } /** * Construct a new resource discoverer. * * @param classLoaders The class loaders holder */ public DiscoverClasses(ClassLoaders classLoaders) { super(classLoaders); } /** * {@inheritDoc} */ @Override public ResourceClassIterator findResourceClasses(final String className) { final String resourceName = className.replace('.','/') + ".class"; if (log.isDebugEnabled()) { log.debug("find: className='" + className + "'"); } return new ResourceClassIterator() { private final Set history = new HashSet(); private int idx = 0; private ResourceClass resource = null; public boolean hasNext() { if (resource == null) { resource = getNextClass(); } return resource != null; } @Override public ResourceClass nextResourceClass() { ResourceClass element = resource; resource = null; return element; } private ResourceClass getNextClass() { while (idx < getClassLoaders().size()) { ClassLoader loader = getClassLoaders().get(idx++); URL url = null; try { url = loader.getResource(resourceName); } catch (UnsupportedOperationException e) { // ignore } if (url == null) { try { CodeSource codeSource = loader.loadClass(className) .getProtectionDomain() .getCodeSource(); if (codeSource != null) { url = new URL(codeSource.getLocation(), resourceName); } // else keep url null } catch (Exception le) { // keep url null } } if (url != null) { if (history.add(url)) { if (log.isDebugEnabled()) { log.debug("getNextClass: next URL='" + url + "'"); } return new ResourceClass(className, url, loader); } if (log.isDebugEnabled()) { log.debug("getNextClass: duplicate URL='" + url + "'"); } } else { if (log.isDebugEnabled()) { log.debug("getNextClass: loader " + loader + ": '" + resourceName + "' not found"); } } } return null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/ClassLoaders.java0000644000175000017500000001525411546704363031225 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource; import java.util.LinkedList; import java.util.List; import org.apache.commons.discovery.jdk.JDKHooks; /** * There are many different contexts in which * loaders can be used. This provides a holder * for a set of class loaders, so that they * don't have to be build back up everytime... */ public class ClassLoaders { protected List classLoaders = new LinkedList(); /** * Construct a new class loader set. */ public ClassLoaders() { } /** * Returns the size of class loaders set. * * @return The size of class loaders set */ public int size() { return classLoaders.size(); } /** * Returns the class loader positioned at the given index. * * @param idx The index the class loader has to be retrieved from * @return The class loader positioned at the given index */ public ClassLoader get(int idx) { return classLoaders.get(idx); } /** * Specify a new class loader to be used in searching. * * The order of loaders determines the order of the result. * It is recommended to add the most specific loaders first; * {@code null} class loaders are discarded. * * @param classLoader The class loader has to added in the set */ public void put(ClassLoader classLoader) { if (classLoader != null) { classLoaders.add(classLoader); } } /** * Specify a new class loader to be used in searching. * The order of loaders determines the order of the result. * It is recommended to add the most specific loaders first; * {@code null} class loaders are discarded. * * @param classLoader The class loader has to added in the set * @param prune if true, verify that the class loader is * not an Ancestor (@see isAncestor) before * adding it to our list. */ public void put(ClassLoader classLoader, boolean prune) { if (classLoader != null && !(prune && isAncestor(classLoader))) { classLoaders.add(classLoader); } } /** * Check to see if classLoader is an * ancestor of any contained class loader. * * This can be used to eliminate redundant class loaders * IF all class loaders defer to parent class loaders * before resolving a class. * * It may be that this is not always true. Therefore, * this check is not done internally to eliminate * redundant class loaders, but left to the discretion * of the user. * * @param classLoader The class loader under test * @return true, if the class loader under test is an ancestor * of any contained class loader, false otherwise */ public boolean isAncestor(final ClassLoader classLoader) { /* bootstrap classloader, at root of all trees! */ if (classLoader == null) { return true; } for (int idx = 0; idx < size(); idx++) { for (ClassLoader walker = get(idx); walker != null; walker = walker.getParent()) { if (walker == classLoader) { return true; } } } return false; } /** * Utility method. Returns a preloaded ClassLoaders instance * containing the following class loaders, in order: * *
    *
  • spi.getClassLoader
  • *
  • seeker.getClassLoader
  • *
  • System Class Loader
  • *
* * Note that the thread context class loader is NOT present. * This is a reasonable set of loaders to try if the resource to be found * should be restricted to a libraries containing the SPI and Factory. * * @param spi WHAT is being looked for (an implementation of this class, * a default property file related to this class). * @param factory WHO is performing the lookup. * @param prune Determines if ancestors are allowed to be loaded or not. * @return The class loaders holder */ public static ClassLoaders getLibLoaders(Class spi, Class factory, boolean prune) { ClassLoaders loaders = new ClassLoaders(); if (spi != null) { loaders.put(spi.getClassLoader()); } if (factory != null) { loaders.put(factory.getClassLoader(), prune); } loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), prune); return loaders; } /** * Utility method. Returns a preloaded ClassLoaders instance * containing the following class loaders, in order: * *
    *
  • Thread Context Class Loader
  • *
  • spi.getClassLoader
  • *
  • seeker.getClassLoader
  • *
  • System Class Loader
  • *
* * Note that the thread context class loader IS present. * This is a reasonable set of loaders to try if the resource to be found * may be provided by an application. * * @param spi WHAT is being looked for (an implementation of this class, * a default property file related to this class). * @param factory WHO is performing the lookup (factory). * @param prune Determines if ancestors are allowed to be loaded or not. * @return The class loaders holder */ public static ClassLoaders getAppLoaders(Class spi, Class factory, boolean prune) { ClassLoaders loaders = new ClassLoaders(); loaders.put(JDKHooks.getJDKHooks().getThreadContextClassLoader()); if (spi != null) { loaders.put(spi.getClassLoader(), prune); } if (factory != null) { loaders.put(factory.getClassLoader(), prune); } loaders.put(JDKHooks.getJDKHooks().getSystemClassLoader(), prune); return loaders; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/DiscoverResources.java0000644000175000017500000001037511547002043032301 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource; import java.io.IOException; import java.net.URL; import java.util.Enumeration; import org.apache.commons.discovery.Resource; import org.apache.commons.discovery.ResourceDiscover; import org.apache.commons.discovery.ResourceIterator; import org.apache.commons.discovery.jdk.JDKHooks; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * */ public class DiscoverResources extends ResourceDiscoverImpl implements ResourceDiscover { private static Log log = LogFactory.getLog(DiscoverResources.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * Construct a new resource discoverer. */ public DiscoverResources() { super(); } /** * Construct a new resource discoverer. * * @param classLoaders The class loaders holder */ public DiscoverResources(ClassLoaders classLoaders) { super(classLoaders); } /** * {@inheritDoc} */ @Override public ResourceIterator findResources(final String resourceName) { if (log.isDebugEnabled()) { log.debug("find: resourceName='" + resourceName + "'"); } return new ResourceIterator() { private int idx = 0; private ClassLoader loader = null; private Enumeration resources = null; private Resource resource = null; public boolean hasNext() { if (resource == null) { resource = getNextResource(); } return resource != null; } @Override public Resource nextResource() { Resource element = resource; resource = null; return element; } private Resource getNextResource() { if (resources == null || !resources.hasMoreElements()) { resources = getNextResources(); } Resource resourceInfo; if (resources != null) { URL url = resources.nextElement(); if (log.isDebugEnabled()) { log.debug("getNextResource: next URL='" + url + "'"); } resourceInfo = new Resource(resourceName, url, loader); } else { resourceInfo = null; } return resourceInfo; } private Enumeration getNextResources() { while (idx < getClassLoaders().size()) { loader = getClassLoaders().get(idx++); if (log.isDebugEnabled()) { log.debug("getNextResources: search using ClassLoader '" + loader + "'"); } try { Enumeration e = JDKHooks.getJDKHooks().getResources(loader, resourceName); if (e != null && e.hasMoreElements()) { return e; } } catch( IOException ex ) { log.warn("getNextResources: Ignoring Exception", ex); } } return null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/0000755000175000017500000000000011643422201027061 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInDictionary.javacommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInDictionary0000644000175000017500000001017611547002043034071 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import java.util.Dictionary; import java.util.Hashtable; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Recover resources from a Dictionary. This covers Properties as well, * since Properties extends Hashtable extends Dictionary. * * The recovered value is expected to be either a String * or a String[]. */ public class DiscoverNamesInDictionary extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(DiscoverNamesInDictionary.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } private Dictionary dictionary; /** * Construct a new resource discoverer with an empty Dictionary. */ public DiscoverNamesInDictionary() { setDictionary(new Hashtable()); } /** * Construct a new resource discoverer with the given Dictionary. * * @param dictionary The initial Dictionary */ public DiscoverNamesInDictionary(Dictionary dictionary) { setDictionary(dictionary); } /** * Returns the current Dictionary for names mapping. * * @return The current Dictionary for names mapping */ protected Dictionary getDictionary() { return dictionary; } /** * Specify the Dictionary for names mapping. * * @param table The Dictionary for names mapping */ public void setDictionary(Dictionary table) { this.dictionary = table; } /** * Add a resource name to a single name mapping. * * @param resourceName The resource name * @param resource The target name */ public void addResource(String resourceName, String resource) { addResource(resourceName, new String[]{ resource }); } /** * Add a resource name to multiple names mapping. * * @param resourceName The resource name * @param resources The target names */ public void addResource(String resourceName, String[] resources) { dictionary.put(resourceName, resources); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String resourceName) { if (log.isDebugEnabled()) { log.debug("find: resourceName='" + resourceName + "'"); } final String[] resources = dictionary.get(resourceName); return new ResourceNameIterator() { private int idx = 0; public boolean hasNext() { if (resources != null) { while (idx < resources.length && resources[idx] == null) { idx++; } return idx < resources.length; } return false; } public String nextResourceName() { return hasNext() ? resources[idx++] : null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/package-info.java0000644000175000017500000000161411546710715032266 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Properties resources discovery catalog. */ package org.apache.commons.discovery.resource.names; commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverServiceNames.java0000644000175000017500000000577211546674174034046 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import org.apache.commons.discovery.ResourceDiscover; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.resource.ClassLoaders; /** * Provide JDK 1.3 style service discovery... * * The caller will first configure the discoverer by creating a * root Discoverer for the files. */ public class DiscoverServiceNames extends DiscoverNamesInFile implements ResourceNameDiscover { protected static final String SERVICE_HOME = "META-INF/services/"; /** * Construct a new service discoverer. */ public DiscoverServiceNames() { super(SERVICE_HOME, null); } /** * Construct a new resource discoverer. * * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverServiceNames(String prefix, String suffix) { super((prefix == null) ? SERVICE_HOME : SERVICE_HOME + prefix, suffix); } /** * Construct a new resource discoverer. * * @param loaders The class loaders holder */ public DiscoverServiceNames(ClassLoaders loaders) { super(loaders, SERVICE_HOME, null); } /** * Construct a new resource discoverer. * * @param loaders The class loaders holder * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverServiceNames(ClassLoaders loaders, String prefix, String suffix) { super(loaders, (prefix == null) ? SERVICE_HOME : SERVICE_HOME + prefix, suffix); } /** * Construct a new service discoverer. * * @param discoverer The discoverer to resolve resources */ public DiscoverServiceNames(ResourceDiscover discoverer) { super(discoverer, SERVICE_HOME, null); } /** * Construct a new service discoverer. * * @param discoverer The discoverer to resolve resources * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverServiceNames(ResourceDiscover discoverer, String prefix, String suffix) { super(discoverer, (prefix == null) ? SERVICE_HOME : SERVICE_HOME + prefix, suffix); } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/NameDiscoverers.java0000644000175000017500000000776611547002043033036 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import java.util.ArrayList; import java.util.List; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Holder for multiple ResourceNameDiscover instances. * * The result is the union of the results from each * (not a chained sequence, where results feed the next in line. */ public class NameDiscoverers extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(NameDiscoverers.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } private final List discoverers = new ArrayList(); /** * Construct a new resource name discoverer */ public NameDiscoverers() { } /** * Specify an discover to be used in searching. * The order of discover determines the order of the result. * It is recommended to add the most specific discover first. * * @param discover The discover to be added */ public void addResourceNameDiscover(ResourceNameDiscover discover) { if (discover != null) { discoverers.add(discover); } } /** * Retrieve the discover positioned at the given index. * * @param idx The discover index position client is requiring * @return The discover positioned at the input index */ protected ResourceNameDiscover getResourceNameDiscover(int idx) { return discoverers.get(idx); } /** * Returns the current size of set discovers. * * @return The current size of set discovers */ protected int size() { return discoverers.size(); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String resourceName) { if (log.isDebugEnabled()) { log.debug("find: resourceName='" + resourceName + "'"); } return new ResourceNameIterator() { private int idx = 0; private ResourceNameIterator iterator = null; public boolean hasNext() { if (iterator == null || !iterator.hasNext()) { iterator = getNextIterator(); if (iterator == null) { return false; } } return iterator.hasNext(); } public String nextResourceName() { return iterator.nextResourceName(); } private ResourceNameIterator getNextIterator() { while (idx < size()) { ResourceNameIterator iter = getResourceNameDiscover(idx++).findResourceNames(resourceName); if (iter.hasNext()) { return iter; } } return null; } }; } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInAlternateManagedProperties.javacommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInAlternateM0000644000175000017500000000654511547002043034025 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import java.util.HashMap; import java.util.Map; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.tools.ManagedProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Recover resource name from Managed Properties, * using OLD property names. * * This class maintains a mapping between old names and * (new) the class names they represent. The discovery * mechanism uses the class names as property names. * * @see org.apache.commons.discovery.tools.ManagedProperties */ public class DiscoverNamesInAlternateManagedProperties extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(DiscoverNamesInAlternateManagedProperties.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } private final Map mapping = new HashMap(); /** * Construct a new resource discoverer. */ public DiscoverNamesInAlternateManagedProperties() { } /** * Add a class name/property name mapping. * * @param className The class name * @param propertyName The property name */ public void addClassToPropertyNameMapping(String className, String propertyName) { mapping.put(className, propertyName); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String resourceName) { final String mappedName = mapping.get(resourceName); if (log.isDebugEnabled()) { if (mappedName == null) { log.debug("find: resourceName='" + resourceName + "', no mapping"); } else { log.debug("find: resourceName='" + resourceName + "', lookup property '" + mappedName + "'"); } } return new ResourceNameIterator() { private String resource = (mappedName == null) ? null : ManagedProperties.getProperty(mappedName); public boolean hasNext() { return resource != null; } public String nextResourceName() { String element = resource; resource = null; return element; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverMappedNames.java0000644000175000017500000000662311547002043033625 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import java.util.Hashtable; import java.util.Map; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Recover resource name from Managed Properties, * using OLD property names. * * This class maintains a mapping between old names and * (new) the class names they represent. The discovery * mechanism uses the class names as property names. * * @see org.apache.commons.discovery.tools.ManagedProperties */ public class DiscoverMappedNames extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(DiscoverMappedNames.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * The String name ==> String[] newNames mapping */ private final Map mapping = new Hashtable(); /** * Construct a new resource discoverer */ public DiscoverMappedNames() { } /** * Maps a name to another name. * * @param fromName The name has to be mapped * @param toName The mapping target */ public void map(String fromName, String toName) { map(fromName, new String[]{ toName }); } /** * Maps a name to multiple names. * * @param fromName The name has to be mapped * @param toNames The mapping targets */ public void map(String fromName, String [] toNames) { mapping.put(fromName, toNames); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String resourceName) { if (log.isDebugEnabled()) { log.debug("find: resourceName='" + resourceName + "', mapping to constants"); } final String[] names = mapping.get(resourceName); return new ResourceNameIterator() { private int idx = 0; public boolean hasNext() { if (names != null) { while (idx < names.length && names[idx] == null) { idx++; } return idx < names.length; } return false; } public String nextResourceName() { return hasNext() ? names[idx++] : null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInFile.java0000644000175000017500000002145511547002043033565 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.apache.commons.discovery.Resource; import org.apache.commons.discovery.ResourceDiscover; import org.apache.commons.discovery.ResourceIterator; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.resource.ClassLoaders; import org.apache.commons.discovery.resource.DiscoverResources; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Discover ALL files of a given name, and return resource names * contained within the set of files: *
    *
  • one resource name per line,
  • *
  • whitespace ignored,
  • *
  • comments begin with '#'
  • *
* * Default discoverer is DiscoverClassLoaderResources, * but it can be set to any other. */ public class DiscoverNamesInFile extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(DiscoverNamesInFile.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } private ResourceDiscover _discoverResources; private final String _prefix; private final String _suffix; /** * Construct a new resource discoverer. */ public DiscoverNamesInFile() { _discoverResources = new DiscoverResources(); _prefix = null; _suffix = null; } /** * Construct a new resource discoverer. * * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverNamesInFile(String prefix, String suffix) { _discoverResources = new DiscoverResources(); _prefix = prefix; _suffix = suffix; } /** * Construct a new resource discoverer. * * @param loaders The class loaders holder */ public DiscoverNamesInFile(ClassLoaders loaders) { _discoverResources = new DiscoverResources(loaders); _prefix = null; _suffix = null; } /** * Construct a new resource discoverer. * * @param loaders The class loaders holder * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverNamesInFile(ClassLoaders loaders, String prefix, String suffix) { _discoverResources = new DiscoverResources(loaders); _prefix = prefix; _suffix = suffix; } /** * Construct a new resource discoverer. * * @param discoverer The discoverer to resolve resources */ public DiscoverNamesInFile(ResourceDiscover discoverer) { _discoverResources = discoverer; _prefix = null; _suffix = null; } /** * Construct a new resource discoverer. * * @param discoverer The discoverer to resolve resources * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverNamesInFile(ResourceDiscover discoverer, String prefix, String suffix) { _discoverResources = discoverer; _prefix = prefix; _suffix = suffix; } /** * Set the discoverer to resolve resources. * * @param discover The discoverer to resolve resources */ public void setDiscoverer(ResourceDiscover discover) { _discoverResources = discover; } /** * Return the discoverer to resolve resources. * * To be used by downstream elements... * * @return The discoverer to resolve resources */ public ResourceDiscover getDiscover() { return _discoverResources; } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String serviceName) { String fileName; if (_prefix != null && _prefix.length() > 0) { fileName = _prefix + serviceName; } else { fileName = serviceName; } if (_suffix != null && _suffix.length() > 0) { fileName = fileName + _suffix; } if (log.isDebugEnabled()) { if (_prefix != null && _suffix != null) { log.debug("find: serviceName='" + serviceName + "' as '" + fileName + "'"); } else { log.debug("find: serviceName = '" + fileName + "'"); } } final ResourceIterator files = getDiscover().findResources(fileName); return new ResourceNameIterator() { private int idx = 0; private List classNames = null; private String resource = null; public boolean hasNext() { if (resource == null) { resource = getNextClassName(); } return resource != null; } public String nextResourceName() { String element = resource; resource = null; return element; } private String getNextClassName() { if (classNames == null || idx >= classNames.size()) { classNames = getNextClassNames(); idx = 0; if (classNames == null) { return null; } } String className = classNames.get(idx++); if (log.isDebugEnabled()) { log.debug("getNextClassResource: next class='" + className + "'"); } return className; } private List getNextClassNames() { while (files.hasNext()) { List results = readServices(files.nextResource()); if (results != null && results.size() > 0) { return results; } } return null; } }; } /** * Parses the resource info file and store all the defined SPI implementation classes * * @param info The resource file * @return The list with all SPI implementation names */ private List readServices(final Resource info) { List results = new ArrayList(); InputStream is = info.getResourceAsStream(); if (is != null) { try { try { // This code is needed by EBCDIC and other // strange systems. It's a fix for bugs // reported in xerces BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is)); } try { String serviceImplName; while( (serviceImplName = rd.readLine()) != null) { int idx = serviceImplName.indexOf('#'); if (idx >= 0) { serviceImplName = serviceImplName.substring(0, idx); } serviceImplName = serviceImplName.trim(); if (serviceImplName.length() != 0) { results.add(serviceImplName); } } } finally { rd.close(); } } finally { is.close(); } } catch (IOException e) { // ignore } } return results; } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInManagedProperties.javacommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInManagedPro0000644000175000017500000000643411547002043034003 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.tools.ManagedProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Recover resource name from Managed Properties. * @see org.apache.commons.discovery.tools.ManagedProperties */ public class DiscoverNamesInManagedProperties extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(DiscoverNamesInManagedProperties.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } private final String _prefix; private final String _suffix; /** * Construct a new resource discoverer. */ public DiscoverNamesInManagedProperties() { this(null, null); } /** * Construct a new resource discoverer. * * @param prefix The resource name prefix * @param suffix The resource name suffix */ public DiscoverNamesInManagedProperties(String prefix, String suffix) { _prefix = prefix; _suffix = suffix; } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String resourceName) { String name; if (_prefix != null && _prefix.length() > 0) { name = _prefix + resourceName; } else { name = resourceName; } if (_suffix != null && _suffix.length() > 0) { name = name + _suffix; } if (log.isDebugEnabled()) { if (_prefix != null && _suffix != null) { log.debug("find: resourceName='" + resourceName + "' as '" + name + "'"); } else { log.debug("find: resourceName = '" + name + "'"); } } final String newResourcName = name; return new ResourceNameIterator() { private String resource = ManagedProperties.getProperty(newResourcName); public boolean hasNext() { return resource != null; } public String nextResourceName() { String element = resource; resource = null; return element; } }; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInSystemProperties.javacommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/DiscoverNamesInSystemProp0000644000175000017500000000442111547002043034105 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Recover resource name from System Properties. */ public class DiscoverNamesInSystemProperties extends ResourceNameDiscoverImpl implements ResourceNameDiscover { private static Log log = LogFactory.getLog(DiscoverNamesInSystemProperties.class); /** * Sets the {@code Log} for this class. * * @param _log This class {@code Log} * @deprecated This method is not thread-safe */ @Deprecated public static void setLog(Log _log) { log = _log; } /** * Construct a new resource discoverer */ public DiscoverNamesInSystemProperties() { } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(final String resourceName) { if (log.isDebugEnabled()) { log.debug("find: resourceName='" + resourceName + "'"); } return new ResourceNameIterator() { private String resource = System.getProperty(resourceName); public boolean hasNext() { return resource != null; } public String nextResourceName() { String element = resource; resource = null; return element; } }; } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootcommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/ResourceNameDiscoverImpl.javacommons-discovery-0.5/src/java/org/apache/commons/discovery/resource/names/ResourceNameDiscoverImpl.0000644000175000017500000000527111546675116034021 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource.names; import org.apache.commons.discovery.ResourceNameDiscover; import org.apache.commons.discovery.ResourceNameIterator; /** * Helper class for methods implementing the ResourceNameDiscover interface. */ public abstract class ResourceNameDiscoverImpl implements ResourceNameDiscover { /** * Locate names of resources that are bound to {@code resourceName}. * * @param resourceName The resource name to locate * @return A new {@link ResourceNameIterator} */ public abstract ResourceNameIterator findResourceNames(String resourceName); /** * Locate names of resources that are bound to {@code inputNames}. * * @param inputNames The resource names to locate * @return A new {@link ResourceNameIterator} */ public ResourceNameIterator findResourceNames(final ResourceNameIterator inputNames) { return new ResourceNameIterator() { private ResourceNameIterator resourceNames = null; private String resourceName = null; public boolean hasNext() { if (resourceName == null) { resourceName = getNextResourceName(); } return resourceName != null; } public String nextResourceName() { String name = resourceName; resourceName = null; return name; } private String getNextResourceName() { while (inputNames.hasNext() && (resourceNames == null || !resourceNames.hasNext())) { resourceNames = findResourceNames(inputNames.nextResourceName()); } return (resourceNames != null && resourceNames.hasNext()) ? resourceNames.nextResourceName() : null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/resource/ResourceDiscoverImpl.java0000644000175000017500000001065211546700571032750 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery.resource; import org.apache.commons.discovery.Resource; import org.apache.commons.discovery.ResourceDiscover; import org.apache.commons.discovery.ResourceIterator; import org.apache.commons.discovery.ResourceNameIterator; import org.apache.commons.discovery.resource.names.ResourceNameDiscoverImpl; /** * Helper class for methods implementing the ResourceDiscover interface. */ public abstract class ResourceDiscoverImpl extends ResourceNameDiscoverImpl implements ResourceDiscover { private ClassLoaders classLoaders; /** * Construct a new resource discoverer. */ public ResourceDiscoverImpl() { } /** * Construct a new resource discoverer. * * @param classLoaders The class laoders holder */ public ResourceDiscoverImpl(ClassLoaders classLoaders) { setClassLoaders(classLoaders); } /** * Specify set of class loaders to be used in searching. * * @param loaders The class laoders holder */ public void setClassLoaders(ClassLoaders loaders) { classLoaders = loaders; } /** * Specify a new class loader to be used in searching. * * The order of loaders determines the order of the result. * It is recommended to add the most specific loaders first. * * @param loader The new class loader to be added */ public void addClassLoader(ClassLoader loader) { getClassLoaders().put(loader); } /** * Returns the class loaders holder. * * @return The class loaders holder */ protected ClassLoaders getClassLoaders() { if (classLoaders == null) { classLoaders = ClassLoaders.getLibLoaders(this.getClass(), null, true); } return classLoaders; } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(String resourceName) { return findResources(resourceName); } /** * {@inheritDoc} */ @Override public ResourceNameIterator findResourceNames(ResourceNameIterator resourceNames) { return findResources(resourceNames); } /** * Locate resources that are bound to {@code resourceName}. * * @param resourceName The resource name has to be located * @return The located resources iterator */ public abstract ResourceIterator findResources(String resourceName); /** * Locate resources that are bound to resourceNames. * * @param inputNames The resources name iterator has to be located * @return The located resources iterator */ public ResourceIterator findResources(final ResourceNameIterator inputNames) { return new ResourceIterator() { private ResourceIterator resources = null; private Resource resource = null; public boolean hasNext() { if (resource == null) { resource = getNextResource(); } return resource != null; } @Override public Resource nextResource() { Resource rsrc = resource; resource = null; return rsrc; } private Resource getNextResource() { while (inputNames.hasNext() && (resources == null || !resources.hasNext())) { resources = findResources(inputNames.nextResourceName()); } return (resources != null && resources.hasNext()) ? resources.nextResource() : null; } }; } } commons-discovery-0.5/src/java/org/apache/commons/discovery/ResourceNameIterator.java0000644000175000017500000000315611546563027031117 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.discovery; /** * Iterate over resource names. * The semantics are somewhat unusual, for better or worse. * hasNext is presumed to be destructive to the current state, * each call will 'move' the cursor. * nextResourceName() MUST BE non-destructive, * it does not change the state. * * TODO: FIX iterator logic/semantics, possibly add 'currentResourceName()'. */ public interface ResourceNameIterator { /** * Returns true if the iteration has more elements. * * @return true if the iterator has more elements, false otherwise */ boolean hasNext(); /** * nextResourceName() returns the name of the next resource, * and MUST be non-destructive. Repeated calls * * @return The next resource name in the iteration */ String nextResourceName(); } commons-discovery-0.5/TODO0000644000175000017500000000025210533410773015424 0ustar drazzibdrazzib2. Review/rewrite javadoc 3. Review/rework best-practices.html 4. NLS enable 5. Create a finer granularity of exceptions.. we only have one for all situations.