pax_global_header00006660000000000000000000000064125720572350014522gustar00rootroot0000000000000052 comment=2d8307585e97fff3a86c34eb86c681ba81bb1811 jboss-modules-1.4.4.Final/000077500000000000000000000000001257205723500153465ustar00rootroot00000000000000jboss-modules-1.4.4.Final/.gitignore000066400000000000000000000002651257205723500173410ustar00rootroot00000000000000# Ignore .svn metadata files .svn #Ignore Maven generated target folders target # Ignore eclipse files .project .classpath .settings # Ignore IDEA files *.iml *.ipr *.iws /.ideajboss-modules-1.4.4.Final/LICENSE.txt000066400000000000000000000261361257205723500172010ustar00rootroot00000000000000 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. jboss-modules-1.4.4.Final/XPP3-LICENSE.txt000066400000000000000000000042171257205723500177250ustar00rootroot00000000000000Indiana University Extreme! Lab Software License Version 1.1.1 Copyright (c) 2002 Extreme! Lab, Indiana University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Indiana University Extreme! Lab (http://www.extreme.indiana.edu/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Indiana Univeristy" and "Indiana Univeristy Extreme! Lab" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact http://www.extreme.indiana.edu/. 5. Products derived from this software may not use "Indiana Univeristy" name nor may "Indiana Univeristy" appear in their name, without prior written permission of the Indiana University. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS, COPYRIGHT HOLDERS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jboss-modules-1.4.4.Final/pom.xml000066400000000000000000000114341257205723500166660ustar00rootroot00000000000000 4.0.0 org.jboss.modules jboss-modules 1.4.4.Final JBoss Modules org.jboss jboss-parent 15 asl http://repository.jboss.org/licenses/apache-2.0.txt repo false false maven-compiler-plugin true true ${skip.compile} ${skip.compile} maven-surefire-plugin true false false true **/*Test.java always maven-jar-plugin org.jboss.modules.Main ${project.version} ${project.artifactId} maven-source-plugin maven-javadoc-plugin net.gleamynode.apiviz.APIviz org.jboss.apiviz apiviz 1.3.2.GA __redirected maven-enforcer-plugin ${skip.enforcer} org.jboss.shrinkwrap shrinkwrap-impl-base 1.2.2 test junit junit 4.11 test jboss-modules-1.4.4.Final/src/000077500000000000000000000000001257205723500161355ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/000077500000000000000000000000001257205723500170615ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/000077500000000000000000000000001257205723500200025ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/__redirected/000077500000000000000000000000001257205723500224125ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/__redirected/__DatatypeFactory.java000066400000000000000000000213601257205723500266600ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A redirecting DatatypeFactory * * @author Jason T. Greene */ @SuppressWarnings("unchecked") public final class __DatatypeFactory extends DatatypeFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(DatatypeFactory.class.getName(), "").equals(__DatatypeFactory.class.getName())) { System.clearProperty(DatatypeFactory.class.getName()); } DatatypeFactory factory = DatatypeFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(DatatypeFactory.class.getName(), __DatatypeFactory.class.getName()); } catch (DatatypeConfigurationException e) { throw new IllegalArgumentException("Problem configuring DatatypeFactory", e); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, DatatypeFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __DatatypeFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(DatatypeFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final DatatypeFactory actual; public Duration newDuration(String lexicalRepresentation) { return actual.newDuration(lexicalRepresentation); } public String toString() { return actual.toString(); } public Duration newDuration(long durationInMilliSeconds) { return actual.newDuration(durationInMilliSeconds); } public Duration newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes, BigDecimal seconds) { return actual.newDuration(isPositive, years, months, days, hours, minutes, seconds); } public Duration newDuration(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds) { return actual.newDuration(isPositive, years, months, days, hours, minutes, seconds); } public Duration newDurationDayTime(String lexicalRepresentation) { return actual.newDurationDayTime(lexicalRepresentation); } public Duration newDurationDayTime(long durationInMilliseconds) { return actual.newDurationDayTime(durationInMilliseconds); } public Duration newDurationDayTime(boolean isPositive, BigInteger day, BigInteger hour, BigInteger minute, BigInteger second) { return actual.newDurationDayTime(isPositive, day, hour, minute, second); } public Duration newDurationDayTime(boolean isPositive, int day, int hour, int minute, int second) { return actual.newDurationDayTime(isPositive, day, hour, minute, second); } public Duration newDurationYearMonth(String lexicalRepresentation) { return actual.newDurationYearMonth(lexicalRepresentation); } public Duration newDurationYearMonth(long durationInMilliseconds) { return actual.newDurationYearMonth(durationInMilliseconds); } public Duration newDurationYearMonth(boolean isPositive, BigInteger year, BigInteger month) { return actual.newDurationYearMonth(isPositive, year, month); } public Duration newDurationYearMonth(boolean isPositive, int year, int month) { return actual.newDurationYearMonth(isPositive, year, month); } public XMLGregorianCalendar newXMLGregorianCalendar() { return actual.newXMLGregorianCalendar(); } public XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation) { return actual.newXMLGregorianCalendar(lexicalRepresentation); } public XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal) { return actual.newXMLGregorianCalendar(cal); } public XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year, int month, int day, int hour, int minute, int second, BigDecimal fractionalSecond, int timezone) { return actual.newXMLGregorianCalendar(year, month, day, hour, minute, second, fractionalSecond, timezone); } public XMLGregorianCalendar newXMLGregorianCalendar(int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone) { return actual.newXMLGregorianCalendar(year, month, day, hour, minute, second, millisecond, timezone); } public XMLGregorianCalendar newXMLGregorianCalendarDate(int year, int month, int day, int timezone) { return actual.newXMLGregorianCalendarDate(year, month, day, timezone); } public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours, int minutes, int seconds, int timezone) { return actual.newXMLGregorianCalendarTime(hours, minutes, seconds, timezone); } public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours, int minutes, int seconds, BigDecimal fractionalSecond, int timezone) { return actual.newXMLGregorianCalendarTime(hours, minutes, seconds, fractionalSecond, timezone); } public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours, int minutes, int seconds, int milliseconds, int timezone) { return actual.newXMLGregorianCalendarTime(hours, minutes, seconds, milliseconds, timezone); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__DocumentBuilderFactory.java000066400000000000000000000160251257205723500301740ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.validation.Schema; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A redirecting DocumentBuilderFactory * * @author David M. Lloyd * @author Jason T. Greene */ public final class __DocumentBuilderFactory extends DocumentBuilderFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(DocumentBuilderFactory.class.getName(), "").equals(__DocumentBuilderFactory.class.getName())) { System.clearProperty(DocumentBuilderFactory.class.getName()); } DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(DocumentBuilderFactory.class.getName(), __DocumentBuilderFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } /** * Init method. */ public static void init() {} public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, DocumentBuilderFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Construct a new instance. */ public __DocumentBuilderFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(DocumentBuilderFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final DocumentBuilderFactory actual; public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { return actual.newDocumentBuilder(); } public void setNamespaceAware(final boolean awareness) { actual.setNamespaceAware(awareness); } public void setValidating(final boolean validating) { actual.setValidating(validating); } public void setIgnoringElementContentWhitespace(final boolean whitespace) { actual.setIgnoringElementContentWhitespace(whitespace); } public void setExpandEntityReferences(final boolean expandEntityRef) { actual.setExpandEntityReferences(expandEntityRef); } public void setIgnoringComments(final boolean ignoreComments) { actual.setIgnoringComments(ignoreComments); } public void setCoalescing(final boolean coalescing) { actual.setCoalescing(coalescing); } public boolean isNamespaceAware() { return actual.isNamespaceAware(); } public boolean isValidating() { return actual.isValidating(); } public boolean isIgnoringElementContentWhitespace() { return actual.isIgnoringElementContentWhitespace(); } public boolean isExpandEntityReferences() { return actual.isExpandEntityReferences(); } public boolean isIgnoringComments() { return actual.isIgnoringComments(); } public boolean isCoalescing() { return actual.isCoalescing(); } public void setAttribute(final String name, final Object value) throws IllegalArgumentException { actual.setAttribute(name, value); } public Object getAttribute(final String name) throws IllegalArgumentException { return actual.getAttribute(name); } public void setFeature(final String name, final boolean value) throws ParserConfigurationException { actual.setFeature(name, value); } public boolean getFeature(final String name) throws ParserConfigurationException { return actual.getFeature(name); } public Schema getSchema() { return actual.getSchema(); } public void setSchema(final Schema schema) { actual.setSchema(schema); } public void setXIncludeAware(final boolean state) { actual.setXIncludeAware(state); } public boolean isXIncludeAware() { return actual.isXIncludeAware(); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__JAXPRedirected.java000066400000000000000000000057751257205723500263260ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * Executes common operations against ALL JAXP redirection classes. * * @author Jason T. Greene */ public class __JAXPRedirected { /** * Change all provided factories to the ones contained in the * specified module using the standard META-INF/services lookup * pattern. * * @param id the id for the jaxp module * @param loader the loader containing the jaxp module */ public static void changeAll(ModuleIdentifier id, ModuleLoader loader) { __DocumentBuilderFactory.changeDefaultFactory(id, loader); __SAXParserFactory.changeDefaultFactory(id, loader); __TransformerFactory.changeDefaultFactory(id, loader); __XPathFactory.changeDefaultFactory(id, loader); __XMLEventFactory.changeDefaultFactory(id, loader); __XMLInputFactory.changeDefaultFactory(id, loader); __XMLOutputFactory.changeDefaultFactory(id, loader); __DatatypeFactory.changeDefaultFactory(id, loader); __SchemaFactory.changeDefaultFactory(id, loader); __XMLReaderFactory.changeDefaultFactory(id, loader); } /** * Restores all JAXP factories to the ones contained in the JDK * system classpath. */ public static void restorePlatformFactory() { __DocumentBuilderFactory.restorePlatformFactory(); __SAXParserFactory.restorePlatformFactory(); __TransformerFactory.restorePlatformFactory(); __XPathFactory.restorePlatformFactory(); __XMLEventFactory.restorePlatformFactory(); __XMLInputFactory.restorePlatformFactory(); __XMLOutputFactory.restorePlatformFactory(); __DatatypeFactory.restorePlatformFactory(); __SchemaFactory.restorePlatformFactory(); __XMLReaderFactory.restorePlatformFactory(); } /** * Initializes the JAXP redirection system. */ public static void initAll() { __DocumentBuilderFactory.init(); __SAXParserFactory.init(); __TransformerFactory.init(); __XPathFactory.init(); __XMLEventFactory.init(); __XMLInputFactory.init(); __XMLOutputFactory.init(); __DatatypeFactory.init(); __SchemaFactory.init(); __XMLReaderFactory.init(); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__RedirectedUtils.java000066400000000000000000000137251257205723500266560ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.UndeclaredThrowableException; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.jboss.modules.Module; import org.jboss.modules.ModuleClassLoader; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoadException; import org.jboss.modules.ModuleLoader; import org.jboss.modules.log.ModuleLogger; /** * Common utilities for redirected factories * * @author David M. Lloyd * @authore Jason T. Greene */ public final class __RedirectedUtils { static ModuleLogger getModuleLogger() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { return AccessController.doPrivileged(new PrivilegedAction() { public ModuleLogger run() { return Module.getModuleLogger(); } }); } else { return Module.getModuleLogger(); } } static RuntimeException rethrowCause(Throwable t) throws Error { try { throw t.getCause(); } catch (Error e) { throw e; } catch (RuntimeException re) { return re; } catch (Throwable throwable) { return new UndeclaredThrowableException(throwable); } } static E wrapped(E e, Throwable orig) { Throwable cause = orig.getCause(); if (cause != null) { e.initCause(cause); } e.setStackTrace(orig.getStackTrace()); return e; } static Class loadProvider(ModuleIdentifier id, Class intf, ModuleLoader moduleLoader) { return loadProvider(id, intf, moduleLoader, null); } static Class loadProvider(ModuleIdentifier id, Class intf, ModuleLoader moduleLoader, String name) { Module module; try { module = moduleLoader.loadModule(id); } catch (ModuleLoadException e) { getModuleLogger().providerUnloadable(id.toString(), null); return null; } ModuleClassLoader classLoader = module.getClassLoader(); return loadProvider(intf, classLoader, name); } static Class loadProvider(Class intf, ClassLoader classLoader) { return loadProvider(intf, classLoader, null); } static Class loadProvider(Class intf, ClassLoader classLoader, String name) { List names = findProviderClassNames(intf, classLoader, name); if (names.isEmpty()) { getModuleLogger().providerUnloadable("Not found", classLoader); return null; } String clazzName = names.get(0); try { return classLoader.loadClass(clazzName).asSubclass(intf); } catch (Exception ignore) { getModuleLogger().providerUnloadable(clazzName, classLoader); return null; } } static List> loadProviders(Class intf, ClassLoader classLoader) { return loadProviders(intf, classLoader, null); } static List> loadProviders(Class intf, ClassLoader classLoader, String name) { List names = findProviderClassNames(intf, classLoader, name); if (names.size() < 1) { getModuleLogger().providerUnloadable("Not found", classLoader); return Collections.emptyList(); } List> classes = new ArrayList>(); for (String className : names) { try { classes.add(classLoader.loadClass(className).asSubclass(intf)); } catch (Exception ignore) { getModuleLogger().providerUnloadable(className, classLoader); } } return classes; } static List findProviderClassNames(Class intf, ClassLoader loader, String name) { if (name == null) name = intf.getName(); final InputStream stream = loader.getResourceAsStream("META-INF/services/" + name); if (stream == null) return Collections.emptyList(); List list = new ArrayList(); try { final BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); String line; while ((line = readLine(reader)) != null) { final int i = line.indexOf('#'); if (i != -1) { line = line.substring(0, i); } line = line.trim(); if (line.length() == 0) continue; list.add(line); } } finally { try { stream.close(); } catch (IOException ignored) { } } return list; } private static String readLine(final BufferedReader reader) { try { return reader.readLine(); } catch (IOException ignore) { return null; } } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__SAXParserFactory.java000066400000000000000000000136721257205723500267240ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.validation.Schema; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; /** * A redirected SAXParserFactory * * @author David M. Lloyd * @authore Jason T. Greene */ public final class __SAXParserFactory extends SAXParserFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(SAXParserFactory.class.getName(), "").equals(__SAXParserFactory.class.getName())) { System.clearProperty(SAXParserFactory.class.getName()); } SAXParserFactory factory = SAXParserFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(SAXParserFactory.class.getName(), __SAXParserFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, SAXParserFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __SAXParserFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(SAXParserFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final SAXParserFactory actual; public SAXParser newSAXParser() throws ParserConfigurationException, SAXException { return actual.newSAXParser(); } public void setNamespaceAware(final boolean awareness) { actual.setNamespaceAware(awareness); } public void setValidating(final boolean validating) { actual.setValidating(validating); } public boolean isNamespaceAware() { return actual.isNamespaceAware(); } public boolean isValidating() { return actual.isValidating(); } public void setFeature(final String name, final boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { actual.setFeature(name, value); } public boolean getFeature(final String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { return actual.getFeature(name); } public Schema getSchema() { return actual.getSchema(); } public void setSchema(final Schema schema) { actual.setSchema(schema); } public void setXIncludeAware(final boolean state) { actual.setXIncludeAware(state); } public boolean isXIncludeAware() { return actual.isXIncludeAware(); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__SchemaFactory.java000066400000000000000000000153171257205723500263120ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.util.List; import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; /** * A redirected SchemaFactory * * @author Jason T. Greene */ public final class __SchemaFactory extends SchemaFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(SchemaFactory.class.getName(), "").equals(__SchemaFactory.class.getName())) { System.clearProperty(SchemaFactory.class.getName()); } SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.W3C_XML_SCHEMA_NS_URI, __SchemaFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, SchemaFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __SchemaFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); SchemaFactory foundInstance = null; try { if (loader != null) { List> providers = __RedirectedUtils.loadProviders(SchemaFactory.class, loader); for (Class provider : providers) { SchemaFactory instance = provider.newInstance(); if (instance.isSchemaLanguageSupported(XMLConstants.W3C_XML_SCHEMA_NS_URI)) { foundInstance = instance; break; } } } actual = foundInstance != null ? foundInstance : factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } } private final SchemaFactory actual; public boolean isSchemaLanguageSupported(String objectModel) { return actual.isSchemaLanguageSupported(objectModel); } public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return actual.getFeature(name); } public void setFeature(String name, boolean value) throws SAXNotSupportedException, SAXNotRecognizedException { actual.setFeature(name, value); } public void setProperty(String name, Object object) throws SAXNotRecognizedException, SAXNotSupportedException { actual.setProperty(name, object); } public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return actual.getProperty(name); } public void setErrorHandler(ErrorHandler errorHandler) { actual.setErrorHandler(errorHandler); } public ErrorHandler getErrorHandler() { return actual.getErrorHandler(); } public void setResourceResolver(LSResourceResolver resourceResolver) { actual.setResourceResolver(resourceResolver); } public LSResourceResolver getResourceResolver() { return actual.getResourceResolver(); } public Schema newSchema(Source schema) throws SAXException { return actual.newSchema(schema); } public Schema newSchema(File schema) throws SAXException { return actual.newSchema(schema); } public Schema newSchema(URL schema) throws SAXException { return actual.newSchema(schema); } public Schema newSchema(Source[] schemas) throws SAXException { return actual.newSchema(schemas); } public Schema newSchema() throws SAXException { return actual.newSchema(); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__TransformerFactory.java000066400000000000000000000204431257205723500274100ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.transform.ErrorListener; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TemplatesHandler; import javax.xml.transform.sax.TransformerHandler; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import org.xml.sax.XMLFilter; /** * A redirected TransformerFactory * * @author David M. Lloyd * @author Jason T. Greene */ public final class __TransformerFactory extends SAXTransformerFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(TransformerFactory.class.getName(), "").equals(__TransformerFactory.class.getName())) { System.clearProperty(TransformerFactory.class.getName()); } TransformerFactory factory = TransformerFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(TransformerFactory.class.getName(), __TransformerFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, TransformerFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __TransformerFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(TransformerFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); saxtual = (actual instanceof SAXTransformerFactory) ? (SAXTransformerFactory)actual : null; } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final TransformerFactory actual; private final SAXTransformerFactory saxtual; // Snicker public Transformer newTransformer(Source source) throws TransformerConfigurationException { return actual.newTransformer(source); } public Transformer newTransformer() throws TransformerConfigurationException { return actual.newTransformer(); } public Templates newTemplates(Source source) throws TransformerConfigurationException { return actual.newTemplates(source); } public String toString() { return actual.toString(); } public Source getAssociatedStylesheet(Source source, String media, String title, String charset) throws TransformerConfigurationException { return actual.getAssociatedStylesheet(source, media, title, charset); } public void setURIResolver(URIResolver resolver) { actual.setURIResolver(resolver); } public URIResolver getURIResolver() { return actual.getURIResolver(); } public void setFeature(String name, boolean value) throws TransformerConfigurationException { actual.setFeature(name, value); } public boolean getFeature(String name) { return actual.getFeature(name); } public void setAttribute(String name, Object value) { actual.setAttribute(name, value); } public Object getAttribute(String name) { return actual.getAttribute(name); } public void setErrorListener(ErrorListener listener) { actual.setErrorListener(listener); } public ErrorListener getErrorListener() { return actual.getErrorListener(); } public TransformerHandler newTransformerHandler(Source src) throws TransformerConfigurationException { if (saxtual == null) throw new TransformerConfigurationException("Provider is not a SAXTransformerFactory"); return saxtual.newTransformerHandler(src); } public TransformerHandler newTransformerHandler(Templates templates) throws TransformerConfigurationException { if (saxtual == null) throw new TransformerConfigurationException("Provider is not a SAXTransformerFactory"); return saxtual.newTransformerHandler(templates); } public TransformerHandler newTransformerHandler() throws TransformerConfigurationException { if (saxtual == null) throw new TransformerConfigurationException("Provider is not a SAXTransformerFactory"); return saxtual.newTransformerHandler(); } public TemplatesHandler newTemplatesHandler() throws TransformerConfigurationException { if (saxtual == null) throw new TransformerConfigurationException("Provider is not a SAXTransformerFactory"); return saxtual.newTemplatesHandler(); } public XMLFilter newXMLFilter(Source src) throws TransformerConfigurationException { if (saxtual == null) throw new TransformerConfigurationException("Provider is not a SAXTransformerFactory"); return saxtual.newXMLFilter(src); } public XMLFilter newXMLFilter(Templates templates) throws TransformerConfigurationException { if (saxtual == null) throw new TransformerConfigurationException("Provider is not a SAXTransformerFactory"); return saxtual.newXMLFilter(templates); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__XMLEventFactory.java000066400000000000000000000222461257205723500265530ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.stream.Location; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.Comment; import javax.xml.stream.events.DTD; import javax.xml.stream.events.EndDocument; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.EntityDeclaration; import javax.xml.stream.events.EntityReference; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.ProcessingInstruction; import javax.xml.stream.events.StartDocument; import javax.xml.stream.events.StartElement; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A redirected XMLEventFactory * * @author David M. Lloyd * @authore Jason T. Greene */ @SuppressWarnings("unchecked") public final class __XMLEventFactory extends XMLEventFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(XMLEventFactory.class.getName(), "").equals(__XMLEventFactory.class.getName())) { System.clearProperty(XMLEventFactory.class.getName()); } XMLEventFactory factory = XMLEventFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(XMLEventFactory.class.getName(), __XMLEventFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, XMLEventFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __XMLEventFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(XMLEventFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final XMLEventFactory actual; public void setLocation(final Location location) { actual.setLocation(location); } public Attribute createAttribute(final String prefix, final String namespaceURI, final String localName, final String value) { return actual.createAttribute(prefix, namespaceURI, localName, value); } public Attribute createAttribute(final String localName, final String value) { return actual.createAttribute(localName, value); } public Attribute createAttribute(final QName name, final String value) { return actual.createAttribute(name, value); } public Namespace createNamespace(final String namespaceURI) { return actual.createNamespace(namespaceURI); } public Namespace createNamespace(final String prefix, final String namespaceUri) { return actual.createNamespace(prefix, namespaceUri); } public StartElement createStartElement(final QName name, final Iterator attributes, final Iterator namespaces) { return actual.createStartElement(name, attributes, namespaces); } public StartElement createStartElement(final String prefix, final String namespaceUri, final String localName) { return actual.createStartElement(prefix, namespaceUri, localName); } public StartElement createStartElement(final String prefix, final String namespaceUri, final String localName, final Iterator attributes, final Iterator namespaces) { return actual.createStartElement(prefix, namespaceUri, localName, attributes, namespaces); } public StartElement createStartElement(final String prefix, final String namespaceUri, final String localName, final Iterator attributes, final Iterator namespaces, final NamespaceContext context) { return actual.createStartElement(prefix, namespaceUri, localName, attributes, namespaces, context); } public EndElement createEndElement(final QName name, final Iterator namespaces) { return actual.createEndElement(name, namespaces); } public EndElement createEndElement(final String prefix, final String namespaceUri, final String localName) { return actual.createEndElement(prefix, namespaceUri, localName); } public EndElement createEndElement(final String prefix, final String namespaceUri, final String localName, final Iterator namespaces) { return actual.createEndElement(prefix, namespaceUri, localName, namespaces); } public Characters createCharacters(final String content) { return actual.createCharacters(content); } public Characters createCData(final String content) { return actual.createCData(content); } public Characters createSpace(final String content) { return actual.createSpace(content); } public Characters createIgnorableSpace(final String content) { return actual.createIgnorableSpace(content); } public StartDocument createStartDocument() { return actual.createStartDocument(); } public StartDocument createStartDocument(final String encoding, final String version, final boolean standalone) { return actual.createStartDocument(encoding, version, standalone); } public StartDocument createStartDocument(final String encoding, final String version) { return actual.createStartDocument(encoding, version); } public StartDocument createStartDocument(final String encoding) { return actual.createStartDocument(encoding); } public EndDocument createEndDocument() { return actual.createEndDocument(); } public EntityReference createEntityReference(final String name, final EntityDeclaration declaration) { return actual.createEntityReference(name, declaration); } public Comment createComment(final String text) { return actual.createComment(text); } public ProcessingInstruction createProcessingInstruction(final String target, final String data) { return actual.createProcessingInstruction(target, data); } public DTD createDTD(final String dtd) { return actual.createDTD(dtd); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__XMLInputFactory.java000066400000000000000000000206621257205723500265710ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.io.InputStream; import java.io.Reader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.stream.EventFilter; import javax.xml.stream.StreamFilter; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLReporter; import javax.xml.stream.XMLResolver; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.util.XMLEventAllocator; import javax.xml.transform.Source; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A redirected XMLInputFactory * * @author David M. Lloyd * @authore Jason T. Greene */ public final class __XMLInputFactory extends XMLInputFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(XMLInputFactory.class.getName(), "").equals(__XMLInputFactory .class.getName())) { System.clearProperty(XMLInputFactory.class.getName()); } XMLInputFactory factory = XMLInputFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(XMLInputFactory.class.getName(), __XMLInputFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, XMLInputFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } /** * Init method. */ public static void init() {} public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Construct a new instance. */ public __XMLInputFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(XMLInputFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final XMLInputFactory actual; public XMLStreamReader createXMLStreamReader(final Reader reader) throws XMLStreamException { return actual.createXMLStreamReader(reader); } public XMLStreamReader createXMLStreamReader(final Source source) throws XMLStreamException { return actual.createXMLStreamReader(source); } public XMLStreamReader createXMLStreamReader(final InputStream stream) throws XMLStreamException { return actual.createXMLStreamReader(stream); } public XMLStreamReader createXMLStreamReader(final InputStream stream, final String encoding) throws XMLStreamException { return actual.createXMLStreamReader(stream, encoding); } public XMLStreamReader createXMLStreamReader(final String systemId, final InputStream stream) throws XMLStreamException { return actual.createXMLStreamReader(systemId, stream); } public XMLStreamReader createXMLStreamReader(final String systemId, final Reader reader) throws XMLStreamException { return actual.createXMLStreamReader(systemId, reader); } public XMLEventReader createXMLEventReader(final Reader reader) throws XMLStreamException { return actual.createXMLEventReader(reader); } public XMLEventReader createXMLEventReader(final String systemId, final Reader reader) throws XMLStreamException { return actual.createXMLEventReader(systemId, reader); } public XMLEventReader createXMLEventReader(final XMLStreamReader reader) throws XMLStreamException { return actual.createXMLEventReader(reader); } public XMLEventReader createXMLEventReader(final Source source) throws XMLStreamException { return actual.createXMLEventReader(source); } public XMLEventReader createXMLEventReader(final InputStream stream) throws XMLStreamException { return actual.createXMLEventReader(stream); } public XMLEventReader createXMLEventReader(final InputStream stream, final String encoding) throws XMLStreamException { return actual.createXMLEventReader(stream, encoding); } public XMLEventReader createXMLEventReader(final String systemId, final InputStream stream) throws XMLStreamException { return actual.createXMLEventReader(systemId, stream); } public XMLStreamReader createFilteredReader(final XMLStreamReader reader, final StreamFilter filter) throws XMLStreamException { return actual.createFilteredReader(reader, filter); } public XMLEventReader createFilteredReader(final XMLEventReader reader, final EventFilter filter) throws XMLStreamException { return actual.createFilteredReader(reader, filter); } public XMLResolver getXMLResolver() { return actual.getXMLResolver(); } public void setXMLResolver(final XMLResolver resolver) { actual.setXMLResolver(resolver); } public XMLReporter getXMLReporter() { return actual.getXMLReporter(); } public void setXMLReporter(final XMLReporter reporter) { actual.setXMLReporter(reporter); } public void setProperty(final String name, final Object value) throws IllegalArgumentException { actual.setProperty(name, value); } public Object getProperty(final String name) throws IllegalArgumentException { return actual.getProperty(name); } public boolean isPropertySupported(final String name) { return actual.isPropertySupported(name); } public void setEventAllocator(final XMLEventAllocator allocator) { actual.setEventAllocator(allocator); } public XMLEventAllocator getEventAllocator() { return actual.getEventAllocator(); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__XMLOutputFactory.java000066400000000000000000000145501257205723500267710ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.io.OutputStream; import java.io.Writer; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.Result; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A redirected XMLOutputFactory * * @author David M. Lloyd * @authore Jason T. Greene */ public final class __XMLOutputFactory extends XMLOutputFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(XMLOutputFactory.class.getName(), "").equals(__XMLOutputFactory.class.getName())) { System.clearProperty(XMLOutputFactory.class.getName()); } XMLOutputFactory factory = XMLOutputFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(XMLOutputFactory.class.getName(), __XMLOutputFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, XMLOutputFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __XMLOutputFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(XMLOutputFactory.class, loader); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final XMLOutputFactory actual; public XMLStreamWriter createXMLStreamWriter(final Writer stream) throws XMLStreamException { return actual.createXMLStreamWriter(stream); } public XMLStreamWriter createXMLStreamWriter(final OutputStream stream) throws XMLStreamException { return actual.createXMLStreamWriter(stream); } public XMLStreamWriter createXMLStreamWriter(final OutputStream stream, final String encoding) throws XMLStreamException { return actual.createXMLStreamWriter(stream, encoding); } public XMLStreamWriter createXMLStreamWriter(final Result result) throws XMLStreamException { return actual.createXMLStreamWriter(result); } public XMLEventWriter createXMLEventWriter(final Result result) throws XMLStreamException { return actual.createXMLEventWriter(result); } public XMLEventWriter createXMLEventWriter(final OutputStream stream) throws XMLStreamException { return actual.createXMLEventWriter(stream); } public XMLEventWriter createXMLEventWriter(final OutputStream stream, final String encoding) throws XMLStreamException { return actual.createXMLEventWriter(stream, encoding); } public XMLEventWriter createXMLEventWriter(final Writer stream) throws XMLStreamException { return actual.createXMLEventWriter(stream); } public void setProperty(final String name, final Object value) throws IllegalArgumentException { actual.setProperty(name, value); } public Object getProperty(final String name) throws IllegalArgumentException { return actual.getProperty(name); } public boolean isPropertySupported(final String name) { return actual.isPropertySupported(name); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__XMLReaderFactory.java000066400000000000000000000147611257205723500266770ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; /** * A redirected SAXParserFactory * * @author David M. Lloyd * @authore Jason T. Greene */ public final class __XMLReaderFactory implements XMLReader { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; private static final String SAX_DRIVER = "org.xml.sax.driver"; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(SAX_DRIVER, "").equals(__XMLReaderFactory.class.getName())) { System.clearProperty(SAX_DRIVER); } XMLReader factory = XMLReaderFactory.createXMLReader(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(SAX_DRIVER, __XMLReaderFactory.class.getName()); } catch (SAXException e) { throw __RedirectedUtils.wrapped(new RuntimeException(e.getMessage()), e); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, XMLReader.class, loader, SAX_DRIVER); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __XMLReaderFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { if (loader != null) { Class provider = __RedirectedUtils.loadProvider(XMLReader.class, loader, SAX_DRIVER); if (provider != null) factory = provider.getConstructor(); } actual = factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } private final XMLReader actual; public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return actual.getFeature(name); } public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { actual.setFeature(name, value); } public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return actual.getProperty(name); } public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { actual.setProperty(name, value); } public void setEntityResolver(EntityResolver resolver) { actual.setEntityResolver(resolver); } public EntityResolver getEntityResolver() { return actual.getEntityResolver(); } public void setDTDHandler(DTDHandler handler) { actual.setDTDHandler(handler); } public DTDHandler getDTDHandler() { return actual.getDTDHandler(); } public void setContentHandler(ContentHandler handler) { actual.setContentHandler(handler); } public ContentHandler getContentHandler() { return actual.getContentHandler(); } public void setErrorHandler(ErrorHandler handler) { actual.setErrorHandler(handler); } public ErrorHandler getErrorHandler() { return actual.getErrorHandler(); } public void parse(InputSource input) throws IOException, SAXException { actual.parse(input); } public void parse(String systemId) throws IOException, SAXException { actual.parse(systemId); } } jboss-modules-1.4.4.Final/src/main/java/__redirected/__XPathFactory.java000066400000000000000000000127721257205723500261400ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package __redirected; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactoryConfigurationException; import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathVariableResolver; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.List; /** * A redirected XPathFactory * * @author Jason T. Greene */ public final class __XPathFactory extends XPathFactory { private static final Constructor PLATFORM_FACTORY; private static volatile Constructor DEFAULT_FACTORY; static { Thread thread = Thread.currentThread(); ClassLoader old = thread.getContextClassLoader(); // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder. // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath) // which is correct. However, after parsing it, it then disables the fallback for the loading of the class. // Thus, the class can not be found. // // Work around the problem by using the System CL, although in the future we may want to just "inherit" // the environment's TCCL thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { if (System.getProperty(XPathFactory.class.getName(), "").equals(__XPathFactory.class.getName())) { System.clearProperty(XPathFactory.class.getName()); } XPathFactory factory = XPathFactory.newInstance(); try { DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } System.setProperty(XPathFactory.class.getName() + ":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI, __XPathFactory.class.getName()); } finally { thread.setContextClassLoader(old); } } public static void changeDefaultFactory(ModuleIdentifier id, ModuleLoader loader) { Class clazz = __RedirectedUtils.loadProvider(id, XPathFactory.class, loader); if (clazz != null) { try { DEFAULT_FACTORY = clazz.getConstructor(); } catch (NoSuchMethodException e) { throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e); } } } public static void restorePlatformFactory() { DEFAULT_FACTORY = PLATFORM_FACTORY; } /** * Init method. */ public static void init() {} /** * Construct a new instance. */ public __XPathFactory() { Constructor factory = DEFAULT_FACTORY; ClassLoader loader = Thread.currentThread().getContextClassLoader(); XPathFactory foundInstance = null; try { if (loader != null) { List> providers = __RedirectedUtils.loadProviders(XPathFactory.class, loader); for (Class provider : providers) { XPathFactory instance = provider.newInstance(); if (instance.isObjectModelSupported(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) { foundInstance = instance; break; } } } actual = foundInstance != null ? foundInstance : factory.newInstance(); } catch (InstantiationException e) { throw __RedirectedUtils.wrapped(new InstantiationError(e.getMessage()), e); } catch (IllegalAccessException e) { throw __RedirectedUtils.wrapped(new IllegalAccessError(e.getMessage()), e); } catch (InvocationTargetException e) { throw __RedirectedUtils.rethrowCause(e); } } private final XPathFactory actual; public boolean isObjectModelSupported(String objectModel) { return actual.isObjectModelSupported(objectModel); } public void setFeature(String name, boolean value) throws XPathFactoryConfigurationException { actual.setFeature(name, value); } public boolean getFeature(String name) throws XPathFactoryConfigurationException { return actual.getFeature(name); } public void setXPathVariableResolver(XPathVariableResolver resolver) { actual.setXPathVariableResolver(resolver); } public void setXPathFunctionResolver(XPathFunctionResolver resolver) { actual.setXPathFunctionResolver(resolver); } public XPath newXPath() { return actual.newXPath(); } } jboss-modules-1.4.4.Final/src/main/java/org/000077500000000000000000000000001257205723500205715ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/000077500000000000000000000000001257205723500217115ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/000077500000000000000000000000001257205723500233615ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/AbstractLocalLoader.java000066400000000000000000000041201257205723500300660ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.List; /** * An abstract local loader implementation. * * @author David M. Lloyd */ public abstract class AbstractLocalLoader implements LocalLoader { /** * Load a class which is locally defined by this loader. Returns {@code null} by default. * * @param name the class name * @param resolve {@code true} to resolve the class * * @return the class, or {@code null} if there is no local class with this name */ public Class loadClassLocal(final String name, final boolean resolve) { return null; } /** * Load a package which is locally defined by this loader. Returns {@code null} by default. * * @param name the package name * * @return the package, or {@code null} if there is no local package with this name */ public Package loadPackageLocal(final String name) { return null; } /** * Load a resource which is locally defined by this loader. The given name is a path separated by "{@code /}" * characters. Returns {@code null} by default. * * @param name the resource path * * @return the resource or resources, or an empty list if there is no local resource with this name */ public List loadResourceLocal(final String name) { return null; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/AbstractResourceLoader.java000066400000000000000000000133461257205723500306350ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.jar.Attributes; import java.util.jar.Manifest; /** * An abstract resource loader implementation. * * @author Carlo de Wolf */ public abstract class AbstractResourceLoader implements ResourceLoader { private static String getDefinedAttribute(Attributes.Name name, Attributes entryAttribute, Attributes mainAttribute) { final String value = entryAttribute == null ? null : entryAttribute.getValue(name); return value == null ? mainAttribute == null ? null : mainAttribute.getValue(name) : value; } /** * Convenience method to get a package specification from a {@code Manifest}. * * @param name the (dot-separated) package name * @param manifest the {@code Manifest} instance * @param rootUrl the code source URL * @return the package specification */ protected static PackageSpec getPackageSpec(final String name, final Manifest manifest, final URL rootUrl) { final PackageSpec spec = new PackageSpec(); if (manifest == null) { return null; } final Attributes mainAttribute = manifest.getMainAttributes(); final String path = name.replace('.', '/').concat("/"); final Attributes entryAttribute = manifest.getAttributes(path); spec.setSpecTitle(getDefinedAttribute(Attributes.Name.SPECIFICATION_TITLE, entryAttribute, mainAttribute)); spec.setSpecVersion(getDefinedAttribute(Attributes.Name.SPECIFICATION_VERSION, entryAttribute, mainAttribute)); spec.setSpecVendor(getDefinedAttribute(Attributes.Name.SPECIFICATION_VENDOR, entryAttribute, mainAttribute)); spec.setImplTitle(getDefinedAttribute(Attributes.Name.IMPLEMENTATION_TITLE, entryAttribute, mainAttribute)); spec.setImplVersion(getDefinedAttribute(Attributes.Name.IMPLEMENTATION_VERSION, entryAttribute, mainAttribute)); spec.setImplVendor(getDefinedAttribute(Attributes.Name.IMPLEMENTATION_VENDOR, entryAttribute, mainAttribute)); if (Boolean.parseBoolean(getDefinedAttribute(Attributes.Name.SEALED, entryAttribute, mainAttribute))) { spec.setSealBase(rootUrl); } return spec; } /** * Get the name of the root represented by this resource loader. Returns an empty string by default. * * @return the name of the root */ public String getRootName() { return ""; } /** * Get the class specification for the given class name. If no matching class is found, {@code null} is returned. * Returns {@code null} by default. * * @param fileName the fileName of the class, e.g. for the class org.jboss.modules.ResourceLoader the * fileName will be org/jboss/modules/ResourceLoader.class * * @return the class specification, or {@code null} if the named class is not found * * @throws java.io.IOException if an I/O error occurs */ public ClassSpec getClassSpec(final String fileName) throws IOException { return null; } /** * Get the package specification for the given directory name. Always returns a package specification; this method * cannot be used to test for the existence of a package. A package spec should always be acquired from the same * resource loader which provided the class specification. The directory name will always be specified using "{@code * /}" separators. Returns {@code null} by default. * * @param name the directory name * * @return the package specification * * @throws java.io.IOException if an I/O error occurs */ public PackageSpec getPackageSpec(final String name) throws IOException { return null; } /** * Get a resource with the given name. If no such resource is available, {@code null} is returned. The resource name * will always be specified using "{@code /}" separators for the directory segments. Returns {@code null} by default. * * @param name the resource name * * @return the resource, or {@code null} if it is not available */ public Resource getResource(final String name) { return null; } /** * Get the absolute physical filesystem path for a library with the given name. The resultant path should be * path-separated using "{@code /}" characters. Returns {@code null} by default. * * @param name the name * * @return the path or {@code null} if the library is not present */ public String getLibrary(final String name) { return null; } /** * Get the collection of resource paths. Called one time only when the resource loader is initialized. The paths * should use "{@code /}" characters to separate the path segments. Returns an empty set by default. * * @return the resource paths */ public Collection getPaths() { return Collections.emptySet(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/AliasModuleSpec.java000066400000000000000000000023171257205723500272410ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * A module specification for a module alias. * * @author David M. Lloyd */ public final class AliasModuleSpec extends ModuleSpec { private final ModuleIdentifier aliasTarget; AliasModuleSpec(final ModuleIdentifier moduleIdentifier, final ModuleIdentifier aliasTarget) { super(moduleIdentifier); this.aliasTarget = aliasTarget; } public ModuleIdentifier getAliasTarget() { return aliasTarget; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/AssertionSetting.java000066400000000000000000000017001257205723500275270ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * The assertion setting for a package or class. * * @apiviz.exclude * * @author David M. Lloyd */ public enum AssertionSetting { ENABLED, DISABLED, INHERIT, }jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/CallerContext.java000066400000000000000000000031621257205723500267750ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.AccessController; import java.security.PrivilegedAction; /** * Various methods for obtaining caller info. * * @author Jason T. Greene */ class CallerContext { private CallerContext() { } private static final class Hack extends SecurityManager { @Override protected Class[] getClassContext() { return super.getClassContext(); } } private static Hack hack = AccessController.doPrivileged(new PrivilegedAction() { @Override public Hack run() { return new Hack(); } }); static Class getCallingClass() { Class stack[] = hack.getClassContext(); int i = 3; while (stack[i] == stack[2]) { // skip nested calls front the same class if (++i >= stack.length) return null; } return stack[i]; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ClassLoaderLocalLoader.java000066400000000000000000000102211257205723500305160ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.UndeclaredThrowableException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; /** * @author David M. Lloyd */ final class ClassLoaderLocalLoader implements LocalLoader { static final ClassLoaderLocalLoader SYSTEM = new ClassLoaderLocalLoader(ClassLoaderLocalLoader.class.getClassLoader()); private static final Method getPackage; private final ClassLoader classLoader; static { getPackage = AccessController.doPrivileged(new PrivilegedAction() { public Method run() { for (Method method : ClassLoader.class.getDeclaredMethods()) { if (method.getName().equals("getPackage")) { Class[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 1 && parameterTypes[0] == String.class) { method.setAccessible(true); return method; } } } throw new IllegalStateException("No getPackage method found on ClassLoader"); } }); } /** * Construct a new instance. * * @param classLoader the classloader to which we delegate */ ClassLoaderLocalLoader(final ClassLoader classLoader) { this.classLoader = classLoader; } // Public members public Class loadClassLocal(final String name, final boolean resolve) { try { return Class.forName(name, resolve, classLoader); } catch (ClassNotFoundException e) { final Throwable cause = e.getCause(); if (cause instanceof Error) { throw (Error) cause; } else if (cause instanceof RuntimeException) { //unlikely throw (RuntimeException) cause; } return null; } } public Package loadPackageLocal(final String name) { try { return (Package) getPackage.invoke(classLoader, name); } catch (IllegalAccessException e) { throw new IllegalAccessError(e.getMessage()); } catch (InvocationTargetException e) { try { throw e.getCause(); } catch (RuntimeException re) { throw re; } catch (Error er) { throw er; } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } } public List loadResourceLocal(final String name) { final Enumeration urls; ClassLoader classLoader = this.classLoader; try { if (classLoader == null) { urls = ClassLoader.getSystemResources(name); } else { urls = classLoader.getResources(name); } } catch (IOException e) { return Collections.emptyList(); } final List list = new ArrayList(); while (urls.hasMoreElements()) { list.add(new URLResource(urls.nextElement())); } return list; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ClassPathModuleLoader.java000066400000000000000000000130111257205723500303770ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.PathFilters; import java.io.File; import java.security.AccessController; import java.util.jar.JarFile; /** * Date: 06.05.2011 * * @author James R. Perkins */ final class ClassPathModuleLoader extends ModuleLoader { static final String[] NO_STRINGS = new String[0]; private final ModuleLoader delegateLoader; private final String classPath; private final String dependencies; private final String mainClass; ClassPathModuleLoader(final ModuleLoader delegateLoader, final String mainClass, String classPath, final String dependencies) { this.delegateLoader = delegateLoader; this.dependencies = dependencies; if (isEmpty(classPath)) { classPath = System.getenv().get("CLASSPATH"); } this.classPath = classPath; AccessController.doPrivileged(new PropertyWriteAction("java.class.path", classPath)); this.mainClass = mainClass; } private static boolean isEmpty(final String classPath) { return classPath == null || classPath.isEmpty(); } @Override protected Module preloadModule(final ModuleIdentifier identifier) throws ModuleLoadException { if (identifier.equals(ModuleIdentifier.CLASSPATH)) { return loadModuleLocal(identifier); } else if (delegateLoader != null) { return preloadModule(identifier, delegateLoader); } else { return null; } } @Override protected ModuleSpec findModule(final ModuleIdentifier moduleIdentifier) throws ModuleLoadException { ModuleSpec.Builder builder = ModuleSpec.build(moduleIdentifier); builder.setMainClass(mainClass); // Process the classpath addClassPath(builder, classPath); // Add the dependencies final String[] dependencyEntries = (dependencies == null ? NO_STRINGS : dependencies.split(",")); for (String dependencyEntry : dependencyEntries) { dependencyEntry = dependencyEntry.trim(); if (! dependencyEntry.isEmpty()) { final ModuleIdentifier depModId = ModuleIdentifier.fromString(dependencyEntry); final DependencySpec spec = DependencySpec.createModuleDependencySpec( PathFilters.getMetaInfSubdirectoriesWithoutMetaInfFilter(), PathFilters.rejectAll(), delegateLoader, depModId, false); builder.addDependency(spec); } } builder.addDependency(DependencySpec.createSystemDependencySpec(JDKPaths.JDK)); builder.addDependency(DependencySpec.createLocalDependencySpec()); return builder.create(); } @Override public String toString() { return "Class path module loader for path '" + classPath + "'"; } /** * Adds the class path entries as dependencies on the builder. * * @param builder the builder to add the dependency entries to. * @param classPath the class path to process * * @throws ModuleLoadException if the class path entry is not found or the entry is a directory. */ private void addClassPath(final ModuleSpec.Builder builder, final String classPath) throws ModuleLoadException { String[] classPathEntries = (classPath == null ? NO_STRINGS : classPath.split(File.pathSeparator)); final File workingDir = new File(System.getProperty("user.dir")); for (String entry : classPathEntries) { if (!entry.isEmpty()) { try { // Find the directory File root = new File(entry); if (! root.isAbsolute()) { root = new File(workingDir, root.getPath()); } if (root.isFile()) { try { builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(ResourceLoaders.createJarResourceLoader(root.getParent(), new JarFile(root, true)))); } catch (Exception e) { Module.log.trace(e, "Resource %s does not appear to be a valid JAR. Loaded as file resource.", root); builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(ResourceLoaders.createFileResourceLoader(entry, root))); } } else { builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(ResourceLoaders.createFileResourceLoader(entry, root))); } } catch (Exception e) { throw new ModuleLoadException(String.format("File %s in class path not valid.", entry), e); } } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ClassSpec.java000066400000000000000000000046441257205723500261140ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.CodeSource; /** * A class definition specification. * * @apiviz.exclude * @author David M. Lloyd */ public final class ClassSpec { private byte[] bytes; private CodeSource codeSource; private AssertionSetting assertionSetting = AssertionSetting.INHERIT; /** * Construct a new instance. */ public ClassSpec() { } /** * Get the class file bytes. * * @return the class file bytes */ public byte[] getBytes() { return bytes; } /** * Set the class file bytes. * * @param bytes the class file bytes */ public void setBytes(final byte[] bytes) { this.bytes = bytes; } /** * Get the code source (should not be {@code null}). * * @return the code source */ public CodeSource getCodeSource() { return codeSource; } /** * Set the code source (should not be {@code null}). * * @param codeSource the code source */ public void setCodeSource(final CodeSource codeSource) { this.codeSource = codeSource; } /** * Get the class assertion setting. * * @return the assertion setting */ public AssertionSetting getAssertionSetting() { return assertionSetting; } /** * Set the class assertion setting. * * @param assertionSetting the assertion setting */ public void setAssertionSetting(final AssertionSetting assertionSetting) { if (assertionSetting == null) { throw new IllegalArgumentException("assertionSetting is null"); } this.assertionSetting = assertionSetting; } }jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ClassifyingModuleLoader.java000066400000000000000000000057631257205723500310070ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.HashMap; import java.util.Map; /** * A module loader which selects a delegate module loader based upon the prefix of the module name. Longer * names are matched first always. * * @author David M. Lloyd */ public final class ClassifyingModuleLoader extends ModuleLoader { private volatile Map delegates; private final ModuleLoader defaultLoader; private final String name; /** * Construct a new instance. The given delegates map is copied. * * @param delegates the default delegates map to use * @param defaultLoader the default loader to use if no delegate mapping exists */ public ClassifyingModuleLoader(final String name, final Map delegates, final ModuleLoader defaultLoader) { super(true, false); this.defaultLoader = defaultLoader; this.delegates = new HashMap(delegates); this.name = name; } /** {@inheritDoc} */ protected Module preloadModule(final ModuleIdentifier moduleIdentifier) throws ModuleLoadException { String name = moduleIdentifier.getName(); int idx; final Map delegates = this.delegates; for (;;) { final ModuleLoader loader = delegates.get(name); if (loader != null) { return preloadModule(moduleIdentifier, loader); } idx = name.lastIndexOf('.'); if (idx == -1) { return preloadModule(moduleIdentifier, defaultLoader); } name = name.substring(0, idx); } } /** {@inheritDoc} */ protected ModuleSpec findModule(final ModuleIdentifier moduleIdentifier) throws ModuleLoadException { // We have no modules of our own! return null; } /** * Change the delegates map. A copy is made of the given map. * * @param delegates the new delegates map to use */ public void setDelegates(Map delegates) { this.delegates = new HashMap(delegates); } public String toString() { return String.format("Classifying Module Loader @%x \"%s\"", Integer.valueOf(hashCode()), name); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ConcreteModuleSpec.java000066400000000000000000000066141257205723500277560ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.lang.instrument.ClassFileTransformer; import java.security.PermissionCollection; import java.util.Map; /** * A {@code Module} specification for a concrete module implementation. * * @apiviz.exclude * * @author John Bailey * @author David M. Lloyd */ public final class ConcreteModuleSpec extends ModuleSpec { private final String mainClass; private final AssertionSetting assertionSetting; private final ResourceLoaderSpec[] resourceLoaders; private final DependencySpec[] dependencies; private final LocalLoader fallbackLoader; private final ModuleClassLoaderFactory moduleClassLoaderFactory; private final ClassFileTransformer classFileTransformer; private final Map properties; private final PermissionCollection permissionCollection; ConcreteModuleSpec(final ModuleIdentifier moduleIdentifier, final String mainClass, final AssertionSetting assertionSetting, final ResourceLoaderSpec[] resourceLoaders, final DependencySpec[] dependencies, final LocalLoader fallbackLoader, final ModuleClassLoaderFactory moduleClassLoaderFactory, final ClassFileTransformer classFileTransformer, final Map properties, final PermissionCollection permissionCollection) { super(moduleIdentifier); this.mainClass = mainClass; this.assertionSetting = assertionSetting; this.resourceLoaders = resourceLoaders; this.dependencies = dependencies; this.fallbackLoader = fallbackLoader; this.moduleClassLoaderFactory = moduleClassLoaderFactory; this.classFileTransformer = classFileTransformer; this.properties = properties; this.permissionCollection = permissionCollection; } public String getMainClass() { return mainClass; } AssertionSetting getAssertionSetting() { return assertionSetting; } ResourceLoaderSpec[] getResourceLoaders() { return resourceLoaders; } DependencySpec[] getDependenciesInternal() { return dependencies; } public DependencySpec[] getDependencies() { return dependencies.length == 0 ? dependencies : dependencies.clone(); } LocalLoader getFallbackLoader() { return fallbackLoader; } ModuleClassLoaderFactory getModuleClassLoaderFactory() { return moduleClassLoaderFactory; } ClassFileTransformer getClassFileTransformer() { return classFileTransformer; } Map getProperties() { return properties; } PermissionCollection getPermissionCollection() { return permissionCollection; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ConcurrentClassLoader.java000066400000000000000000000656661257205723500305060ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.net.URL; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.Locale; import java.util.Queue; import sun.misc.Unsafe; /** * A classloader which can delegate to multiple other classloaders without risk of deadlock. A concurrent class loader * should only ever be delegated to by another concurrent class loader; however a concurrent class loader may * delegate to a standard hierarchical class loader. In other words, holding a lock on another class loader while invoking * a method on this class loader may cause an unexpected deadlock. * * @author David M. Lloyd */ public abstract class ConcurrentClassLoader extends ClassLoader { private static final boolean LOCKLESS; private static final boolean SAFE_JDK; private static final boolean JDK7_PLUS; private static final ClassLoader definingLoader = ConcurrentClassLoader.class.getClassLoader(); private static final ThreadLocal GET_PACKAGE_SUPPRESSOR = new ThreadLocal(); static { boolean jdk7plus = false; boolean parallelOk = true; try { jdk7plus = parallelOk = ClassLoader.registerAsParallelCapable(); } catch (Throwable ignored) { } if (! parallelOk) { throw new Error("Failed to register " + ConcurrentClassLoader.class.getName() + " as parallel-capable"); } /* This resolves a known deadlock that can occur if one thread is in the process of defining a package as part of defining a class, and another thread is defining the system package that can result in loading a class. One holds the Package.pkgs lock and one holds the Classloader lock. */ Package.getPackages(); // Determine whether to run in lockless mode boolean hasUnsafe = false; // For 1.6, we require Unsafe to perform lockless stuff if (! jdk7plus) try { Class.forName("sun.misc.Unsafe", false, null); hasUnsafe = true; } catch (Throwable t) { // ignored } final boolean isJRockit = AccessController.doPrivileged(new PropertyReadAction("java.vm.name", "")).toUpperCase(Locale.US).contains("JROCKIT"); // But the user is always right, so if they override, respect it LOCKLESS = Boolean.parseBoolean(AccessController.doPrivileged(new PropertyReadAction("jboss.modules.lockless", Boolean.toString(! jdk7plus && hasUnsafe && ! isJRockit)))); // If the JDK has safe CL, set this flag SAFE_JDK = Boolean.parseBoolean(AccessController.doPrivileged(new PropertyReadAction("jboss.modules.safe-jdk", Boolean.toString(jdk7plus || isJRockit)))); JDK7_PLUS = jdk7plus; } /** * An empty enumeration, for subclasses to use if desired. */ protected static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.emptySet()); /** * Construct a new instance with the given parent class loader, which must be a concurrent class loader, or {@code null} * to create a root concurrent class loader. * * @param parent the parent class loader */ protected ConcurrentClassLoader(final ConcurrentClassLoader parent) { super(parent == null ? ConcurrentClassLoader.class.getClassLoader() : parent); if (JDK7_PLUS) { if (getClassLoadingLock("$TEST$") == this) { throw new Error("Cannot instantiate non-parallel subclass"); } } } /** * Construct a new instance, using our class loader as the parent. */ protected ConcurrentClassLoader() { super(ConcurrentClassLoader.class.getClassLoader()); if (JDK7_PLUS) { if (getClassLoadingLock("$TEST$") == this) { throw new Error("Cannot instantiate non-parallel subclass"); } } } /** * Loads the class with the specified binary name. Equivalent to calling {@link #loadClass(String, boolean) loadClass(className, false)}. * * @param className The binary name of the class * @return the resulting {@code Class} instance * @throws ClassNotFoundException if the class was not found */ @Override public final Class loadClass(final String className) throws ClassNotFoundException { return performLoadClass(className, false, false); } /** * Loads the class with the specified binary name. * * @param className The binary name of the class * @param resolve {@code true} if the class should be linked after loading * @return the resulting {@code Class} instance */ @Override public final Class loadClass(final String className, boolean resolve) throws ClassNotFoundException { return performLoadClass(className, false, resolve); } /** * Same as {@link #loadClass(String)}, except only exported classes will be considered. * * @param className the class name * @return the class * @throws ClassNotFoundException if the class isn't found */ public final Class loadExportedClass(final String className) throws ClassNotFoundException { return performLoadClass(className, true, false); } /** * Same as {@link #loadClass(String,boolean)}, except only exported classes will be considered. * * @param className the class name * @param resolve {@code true} if the class should be linked after loading * @return the class * @throws ClassNotFoundException if the class isn't found */ public final Class loadExportedClass(final String className, boolean resolve) throws ClassNotFoundException { return performLoadClass(className, true, resolve); } /** * Find a class, possibly delegating to other loader(s). This method should never synchronize across a * delegation method call of any sort. The default implementation always throws {@code ClassNotFoundException}. *

* If a class is to be defined by this method, it should be done via one of the atomic {@code defineOrLoadClass} * methods rather than {@code defineClass()} in order to avoid spurious exceptions. * * @param className the class name * @param exportsOnly {@code true} if only exported classes should be considered * @param resolve {@code true} if the class should be linked after loading * @return the class * @throws ClassNotFoundException if the class is not found */ protected Class findClass(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException { throw new ClassNotFoundException(className); } /** * Atomically define or load the named class. If the class is already defined, the existing class is returned. * * @param className the class name to define or load * @param bytes the bytes to use to define the class * @param off the offset into the byte array at which the class bytes begin * @param len the number of bytes in the class * @return the class */ protected final Class defineOrLoadClass(final String className, final byte[] bytes, int off, int len) { try { final Class definedClass = defineClass(className, bytes, off, len); return definedClass; } catch (LinkageError e) { final Class loadedClass = findLoadedClass(className); if (loadedClass != null) { return loadedClass; } throw e; } } /** * Atomically define or load the named class. If the class is already defined, the existing class is returned. * * @param className the class name to define or load * @param bytes the bytes to use to define the class * @param off the offset into the byte array at which the class bytes begin * @param len the number of bytes in the class * @param protectionDomain the protection domain for the defined class * @return the class */ protected final Class defineOrLoadClass(final String className, final byte[] bytes, int off, int len, ProtectionDomain protectionDomain) { try { final Class definedClass = defineClass(className, bytes, off, len, protectionDomain); return definedClass; } catch (LinkageError e) { final Class loadedClass = findLoadedClass(className); if (loadedClass != null) { return loadedClass; } throw e; } } /** * Implementation of {@link ClassLoader#findClass(String)}. * * @param className the class name * @return the result of {@code findClass(className, false, false)} */ protected final Class findClass(final String className) throws ClassNotFoundException { return findClass(className, false, false); } /** * Finds the resource with the given name. The name of a resource is a {@code '/'}-separated path name that * identifies the resource. If the resource name starts with {@code "java/"} then the parent class loader is used. * Otherwise, this method delegates to {@link #findResource(String, boolean)}. * * @param name the name of the resource * @return the resource URL, or {@code null} if no such resource exists or the invoker does not have adequate * permission to access it */ public final URL getResource(final String name) { for (String s : Module.systemPaths) { if (name.startsWith(s)) { // Whatever loads jboss-modules.jar should have it's classes accessible. // This could even be the bootclasspath, in which case CL is null, and we prefer the system CL return definingLoader != null ? definingLoader.getResource(name) : ClassLoader.getSystemResource(name); } } return findResource(name, false); } /** * Finds all available resources with the given name. * * @see #getResource(String) * * @param name the resource name * @return an enumeration over all the resource URLs; if no resources could be found, the enumeration will be empty * @throws IOException if an I/O error occurs */ public final Enumeration getResources(final String name) throws IOException { for (String s : Module.systemPaths) { if (name.startsWith(s)) { return definingLoader != null ? definingLoader.getResources(name) : ClassLoader.getSystemResources(name); } } return findResources(name, false); } /** * Find the resource with the given name and exported status. * * @see #getResource(String) * * @param name the resource name * @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources * @return the resource URL */ protected URL findResource(final String name, final boolean exportsOnly) { return null; } /** * Never used. {@link ClassLoader#getResource(String)} and related methods can cause a loop condition * when this method is implemented; use {@link #findResource(String, boolean)} instead. * * @param name ignored * @return {@code null} always */ protected final URL findResource(final String name) { // Always return null so that we don't go into a loop from super.getResource*(). return null; } /** * Finds the resources with the given name and exported status. * * @see #getResources(String) * * @param name the resource name * @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources * @return the resource enumeration * @throws IOException if an I/O error occurs */ protected Enumeration findResources(final String name, final boolean exportsOnly) throws IOException { return EMPTY_ENUMERATION; } /** * Never used. {@link ClassLoader#getResources(String)} and related methods can cause a loop condition * when this method is implemented; use {@link #findResources(String, boolean)} instead. By default, returns * an empty enumeration. * * @param name ignored * @return an empty enumeration */ protected final Enumeration findResources(final String name) { return EMPTY_ENUMERATION; } /** * Finds the resource with the given name and exported status, returning the resource content as a stream. * * @param name the resource name * @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources * @return the resource stream, or {@code null} if the resource is not found */ protected InputStream findResourceAsStream(final String name, final boolean exportsOnly) { final URL url = findResource(name, exportsOnly); try { return url == null ? null : url.openStream(); } catch (IOException e) { return null; } } /** * Returns an input stream for reading the specified resource. If the resource starts with {@code "java/"}, then * this method delegates to the parent class loader. Otherwise, this method delegates to {@link #findResourceAsStream(String, boolean)}. * * @param name the resource name * @return the resource stream, or {@code null} if the resource is not found */ public final InputStream getResourceAsStream(final String name) { for (String s : Module.systemPaths) { if (name.startsWith(s)) { return definingLoader != null ? definingLoader.getResourceAsStream(name) : ClassLoader.getSystemResourceAsStream(name); } } return findResourceAsStream(name, false); } // Private members /** * Perform a class load operation. If the class is in the package or a subpackage of a package in the system packages list, * the parent class loader is used to load the class. Otherwise, this method checks to see if the class loader * object is locked; if so, it unlocks it and submits the request to the class loader thread. Otherwise, it will * load the class itself by delegating to {@link #findClass(String, boolean, boolean)}. * * @param className the class name * @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources * @param resolve {@code true} to resolve the loaded class * @return the class returned by {@link #findClass(String, boolean, boolean)} * @throws ClassNotFoundException if {@link #findClass(String, boolean, boolean)} throws this exception */ private Class performLoadClass(String className, boolean exportsOnly, final boolean resolve) throws ClassNotFoundException { if (className == null) { throw new IllegalArgumentException("name is null"); } for (String s : Module.systemPackages) { if (className.startsWith(s)) { return definingLoader != null ? definingLoader.loadClass(className) : findSystemClass(className); } } return performLoadClassChecked(className, exportsOnly, resolve); } /** * Perform a class load operation. This method checks to see if the class loader object is locked; if so, it * unlocks it and submits the request to the class loader thread. Otherwise, it will load the class itself by * delegating to {@link #findClass(String, boolean, boolean)}. *

* If the {@code jboss.modules.unsafe-locks} system property is set to {@code true}, then rather than using the * class loading thread, the lock is forcibly broken and the load retried. * * @param className the class name * @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources * @param resolve {@code true} to resolve the loaded class * @return the class returned by {@link #findClass(String, boolean, boolean)} * @throws ClassNotFoundException if {@link #findClass(String, boolean, boolean)} throws this exception */ private Class performLoadClassChecked(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException { if (SAFE_JDK) { return performLoadClassUnchecked(className, exportsOnly, resolve); } else if (Thread.holdsLock(this)) { if (LOCKLESS) { final Unsafe unsafe = UnsafeHolder.UNSAFE; unsafe.monitorExit(this); try { return performLoadClassChecked(className, exportsOnly, resolve); } finally { unsafe.monitorEnter(this); } } if (Thread.currentThread() != LoaderThreadHolder.LOADER_THREAD) { // Only the classloader thread may take this lock; use a condition to relinquish it final LoadRequest req = new LoadRequest(className, resolve, exportsOnly, this, AccessController.getContext()); final Queue queue = LoaderThreadHolder.REQUEST_QUEUE; synchronized (queue) { queue.add(req); queue.notify(); } boolean intr = false; try { while (!req.done) try { wait(); } catch (InterruptedException e) { intr = true; } } finally { if (intr) Thread.currentThread().interrupt(); } final Class result = req.result; if (result == null) { final String message = req.message; throw new ClassNotFoundException(message == null ? className : message); } return result; } } // no deadlock risk! Either the lock isn't held, or we're inside the class loader thread. return performLoadClassUnchecked(className, exportsOnly, resolve); } private Class performLoadClassUnchecked(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException { if (className.charAt(0) == '[') { // Use Class.forName to load the array type final Class array = Class.forName(className, false, this); if (resolve) { resolveClass(array); } return array; } return findClass(className, exportsOnly, resolve); } private final UnlockedReadHashMap packages = new UnlockedReadHashMap(64); /** * Load a package which is visible to this class loader. * * @param name the package name * @return the package, or {@code null} if no such package is visible to this class loader */ protected final Package getPackage(final String name) { final String packageName = name + "."; for (String s : Module.systemPackages) { if (packageName.startsWith(s)) { return Package.getPackage(name); } } if (GET_PACKAGE_SUPPRESSOR.get() == Boolean.TRUE) { return null; } return getPackageByName(name); } /** * Perform the actual work to load a package which is visible to this class loader. By default, uses a simple * parent-first delegation strategy. * * @param name the package name * @return the package, or {@code null} if no such package is visible to this class loader */ protected Package getPackageByName(final String name) { final Package parentPackage = super.getPackage(name); return parentPackage == null ? findLoadedPackage(name) : parentPackage; } /** * Get all defined packages which are visible to this class loader. * * @return the packages */ protected Package[] getPackages() { ArrayList list = new ArrayList(); list.addAll(packages.values()); list.addAll(Arrays.asList(super.getPackages())); return list.toArray(new Package[list.size()]); } /** * Load a package from this class loader only. * * @param name the package name * @return the package or {@code null} if no such package is defined by this class loader */ protected final Package findLoadedPackage(final String name) { return packages.get(name); } /** * Defines a package by name in this ConcurrentClassLoader. If the package was already defined, the * existing package is returned instead. * * @param name the package name * @param specTitle the specification title * @param specVersion the specification version * @param specVendor the specification vendor * @param implTitle the implementation title * @param implVersion the implementation version * @param implVendor the implementation vendor * @param sealBase if not {@code null}, then this package is sealed with respect to the given code source URL * * @return the newly defined package, or the existing one if one was already defined */ protected Package definePackage(final String name, final String specTitle, final String specVersion, final String specVendor, final String implTitle, final String implVersion, final String implVendor, final URL sealBase) throws IllegalArgumentException { ThreadLocal suppressor = GET_PACKAGE_SUPPRESSOR; suppressor.set(Boolean.TRUE); try { Package existing = packages.get(name); if (existing != null) { return existing; } Package pkg = super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase); existing = packages.putIfAbsent(name, pkg); return existing != null ? existing : pkg; } finally { suppressor.remove(); } } static final class LoaderThreadHolder { static final Thread LOADER_THREAD; static final Queue REQUEST_QUEUE = new ArrayDeque(); static { Thread thr = new LoaderThread(); thr.setName("ClassLoader Thread"); // This thread will always run as long as the VM is alive. thr.setDaemon(true); thr.start(); LOADER_THREAD = thr; } private LoaderThreadHolder() { } } static class LoadRequest { private final String className; private final boolean resolve; private final ConcurrentClassLoader requester; private final AccessControlContext context; Class result; String message; private boolean exportsOnly; boolean done; LoadRequest(final String className, final boolean resolve, final boolean exportsOnly, final ConcurrentClassLoader requester, final AccessControlContext context) { this.className = className; this.resolve = resolve; this.exportsOnly = exportsOnly; this.requester = requester; this.context = context; } } static class LoaderThread extends Thread { @Override public void interrupt() { // no interruption } @Override public void run() { final Queue queue = LoaderThreadHolder.REQUEST_QUEUE; for (; ;) { try { LoadRequest request; synchronized (queue) { while ((request = queue.poll()) == null) { queue.wait(); } } final ConcurrentClassLoader loader = request.requester; Class result = null; synchronized (loader) { try { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { final LoadRequest localRequest = request; result = AccessController.doPrivileged(new PrivilegedExceptionAction>() { public Class run() throws ClassNotFoundException { return loader.performLoadClassChecked(localRequest.className, localRequest.exportsOnly, localRequest.resolve); } }, request.context); } else try { result = loader.performLoadClassChecked(request.className, request.exportsOnly, request.resolve); } catch (ClassNotFoundException e) { request.message = e.getMessage(); } } finally { // no matter what, the requester MUST be notified request.result = result; request.done = true; loader.notifyAll(); } } } catch (Throwable t) { // ignore } } } } private static final class UnsafeHolder { static Unsafe UNSAFE; static { try { final Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); UNSAFE = (Unsafe) field.get(null); } catch (IllegalAccessException e) { throw new IllegalAccessError(e.getMessage()); } catch (NoSuchFieldException e) { throw new NoSuchFieldError(e.getMessage()); } } private UnsafeHolder() { } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/DefaultBootModuleLoaderHolder.java000066400000000000000000000045431257205723500320750ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.lang.reflect.InvocationTargetException; import java.security.AccessController; import java.security.PrivilegedAction; final class DefaultBootModuleLoaderHolder { static final ModuleLoader INSTANCE; private DefaultBootModuleLoaderHolder() { } static { INSTANCE = AccessController.doPrivileged(new PrivilegedAction() { public ModuleLoader run() { final String loaderClass = System.getProperty("boot.module.loader", LocalModuleLoader.class.getName()); try { return Class.forName(loaderClass, true, DefaultBootModuleLoaderHolder.class.getClassLoader()).asSubclass(ModuleLoader.class).getConstructor().newInstance(); } catch (InstantiationException e) { throw new InstantiationError(e.getMessage()); } catch (IllegalAccessException e) { throw new IllegalAccessError(e.getMessage()); } catch (InvocationTargetException e) { try { throw e.getCause(); } catch (RuntimeException cause) { throw cause; } catch (Error cause) { throw cause; } catch (Throwable t) { throw new Error(t); } } catch (NoSuchMethodException e) { throw new NoSuchMethodError(e.getMessage()); } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.getMessage()); } } }); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Dependency.java000066400000000000000000000075141257205723500263110ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.ClassFilters; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * A dependency item. * * @author John Bailey * @author David M. Lloyd */ abstract class Dependency { private final PathFilter exportFilter; private final PathFilter importFilter; private final PathFilter resourceExportFilter; private final PathFilter resourceImportFilter; private final ClassFilter classExportFilter; private final ClassFilter classImportFilter; Dependency(final PathFilter exportFilter, final PathFilter importFilter) { this(exportFilter, importFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll()); } protected Dependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter) { if (exportFilter == null) { throw new IllegalArgumentException("exportFilter is null"); } if (importFilter == null) { throw new IllegalArgumentException("importFilter is null"); } if (resourceExportFilter == null) { throw new IllegalArgumentException("resourceExportFilter is null"); } if (resourceImportFilter == null) { throw new IllegalArgumentException("resourceImportFilter is null"); } if (classExportFilter == null) { throw new IllegalArgumentException("classExportFilter is null"); } if (classImportFilter == null) { throw new IllegalArgumentException("classImportFilter is null"); } this.exportFilter = exportFilter; this.importFilter = importFilter; this.resourceExportFilter = resourceExportFilter; this.resourceImportFilter = resourceImportFilter; this.classExportFilter = classExportFilter; this.classImportFilter = classImportFilter; } /** * Get the export filter for this dependency. This filter determines what imported paths are re-exported by this * dependency. All exported paths must also satisfy the import filter. * * @return the export filter */ final PathFilter getExportFilter() { return exportFilter; } /** * Get the import filter for this dependency. This filter determines what exported paths are imported from the * dependency to the dependent. * * @return the import filter */ final PathFilter getImportFilter() { return importFilter; } final PathFilter getResourceExportFilter() { return resourceExportFilter; } final PathFilter getResourceImportFilter() { return resourceImportFilter; } final ClassFilter getClassExportFilter() { return classExportFilter; } final ClassFilter getClassImportFilter() { return classImportFilter; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/DependencySpec.java000066400000000000000000000532311257205723500271210ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Set; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.ClassFilters; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * A dependency specification that represents a single dependency for a module. The dependency can be on a local loader * or another module, or on the target module's local loader. * * @apiviz.exclude * * @author David M. Lloyd * @author John Bailey * @author Jason T. Greene */ public abstract class DependencySpec { final PathFilter importFilter; final PathFilter exportFilter; final PathFilter resourceImportFilter; final PathFilter resourceExportFilter; final ClassFilter classImportFilter; final ClassFilter classExportFilter; /** * Get the dependency import filter. * * @return the import filter */ public PathFilter getImportFilter() { return importFilter; } /** * Get the dependency export filter. * * @return the export filter */ public PathFilter getExportFilter() { return exportFilter; } /** * Get the dependency resource import filter. * * @return the import filter */ public PathFilter getResourceImportFilter() { return resourceImportFilter; } /** * Get the dependency resource export filter. * * @return the export filter */ public PathFilter getResourceExportFilter() { return resourceExportFilter; } /** * Get the dependency class import filter. * * @return the class import filter */ public ClassFilter getClassImportFilter() { return classImportFilter; } /** * Get the dependency class export filter. * * @return the class export filter */ public ClassFilter getClassExportFilter() { return classExportFilter; } DependencySpec(final PathFilter importFilter, final PathFilter exportFilter) { this(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll()); } DependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter) { this.importFilter = importFilter; this.exportFilter = exportFilter; this.resourceImportFilter = resourceImportFilter; this.resourceExportFilter = resourceExportFilter; this.classImportFilter = classImportFilter; this.classExportFilter = classExportFilter; } abstract Dependency getDependency(final Module module); /** * Create a dependency on the current module's local resources. You should have at least one such dependency * on any module which has its own resources. * * @return the dependency spec */ public static DependencySpec createLocalDependencySpec() { return createLocalDependencySpec(PathFilters.acceptAll(), PathFilters.acceptAll()); } /** * Create a dependency on the current module's local resources. You should have at least one such dependency * on any module which has its own resources. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @return the dependency spec */ public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter) { if (importFilter == null) { throw new IllegalArgumentException("importFilter is null"); } if (exportFilter == null) { throw new IllegalArgumentException("exportFilter is null"); } return new DependencySpec(importFilter, exportFilter) { Dependency getDependency(final Module module) { return new ModuleClassLoaderDependency(exportFilter, importFilter, module.getClassLoaderPrivate()); } public String toString() { return "dependency on local resources"; } }; } /** * Create a dependency on the current module's local resources. You should have at least one such dependency * on any module which has its own resources. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param resourceImportFilter the resource import filter to apply * @param resourceExportFilter the resource export filter to apply * @param classImportFilter the class import filter to apply * @param classExportFilter the class export filter to apply * @return the dependency spec */ public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter) { if (importFilter == null) { throw new IllegalArgumentException("importFilter is null"); } if (exportFilter == null) { throw new IllegalArgumentException("exportFilter is null"); } if (classImportFilter == null) { throw new IllegalArgumentException("classImportFilter is null"); } if (classExportFilter == null) { throw new IllegalArgumentException("classExportFilter is null"); } if (resourceImportFilter == null) { throw new IllegalArgumentException("resourceImportFilter is null"); } if (resourceExportFilter == null) { throw new IllegalArgumentException("resourceExportFilter is null"); } return new DependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter) { Dependency getDependency(final Module module) { return new ModuleClassLoaderDependency(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter, module.getClassLoaderPrivate()); } public String toString() { return "dependency on filtered local resources"; } }; } /** * Create a system dependency. * * @param loaderPaths the set of paths to use from the system class loader * @return the dependency spec */ public static DependencySpec createSystemDependencySpec(final Set loaderPaths) { return createLocalDependencySpec(ClassLoaderLocalLoader.SYSTEM, loaderPaths); } /** * Create a system dependency. * * @param loaderPaths the set of paths to use from the system class loader * @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported * @return the dependency spec */ public static DependencySpec createSystemDependencySpec(final Set loaderPaths, boolean export) { return createLocalDependencySpec(ClassLoaderLocalLoader.SYSTEM, loaderPaths, export); } /** * Create a system dependency. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param loaderPaths the set of paths to use from the system class loader * @return the dependency spec */ public static DependencySpec createSystemDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final Set loaderPaths) { return createLocalDependencySpec(importFilter, exportFilter, ClassLoaderLocalLoader.SYSTEM, loaderPaths); } /** * Create a dependency on the given class loader. * * @param classLoader the class loader * @param loaderPaths the set of paths to use from this class loader * @return the dependency spec */ public static DependencySpec createClassLoaderDependencySpec(final ClassLoader classLoader, final Set loaderPaths) { return createLocalDependencySpec(new ClassLoaderLocalLoader(classLoader), loaderPaths); } /** * Create a dependency on the given class loader. * * @param classLoader the class loader * @param loaderPaths the set of paths to use from this class loader * @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported * @return the dependency spec */ public static DependencySpec createClassLoaderDependencySpec(final ClassLoader classLoader, final Set loaderPaths, boolean export) { return createLocalDependencySpec(new ClassLoaderLocalLoader(classLoader), loaderPaths, export); } /** * Create a dependency on the given class loader. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param classLoader the class loader * @param loaderPaths the set of paths to use from this class loader * @return the dependency spec */ public static DependencySpec createClassLoaderDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ClassLoader classLoader, final Set loaderPaths) { return createLocalDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), new ClassLoaderLocalLoader(classLoader), loaderPaths); } /** * Create a dependency on the given local loader. * * @param localLoader the local loader * @param loaderPaths the set of paths that is exposed by the local loader * @return the dependency spec */ public static DependencySpec createLocalDependencySpec(final LocalLoader localLoader, final Set loaderPaths) { return createLocalDependencySpec(PathFilters.acceptAll(), PathFilters.rejectAll(), localLoader, loaderPaths); } /** * Create a dependency on the given local loader. * * @param localLoader the local loader * @param loaderPaths the set of paths that is exposed by the local loader * @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported * @return the dependency spec */ public static DependencySpec createLocalDependencySpec(final LocalLoader localLoader, final Set loaderPaths, boolean export) { return createLocalDependencySpec(PathFilters.acceptAll(), export ? PathFilters.getDefaultImportFilter() : PathFilters.rejectAll(), localLoader, loaderPaths); } /** * Create a dependency on the given local loader. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param localLoader the local loader * @param loaderPaths the set of paths that is exposed by the local loader * @return the dependency spec */ public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final LocalLoader localLoader, final Set loaderPaths) { return createLocalDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), localLoader, loaderPaths); } /** * Create a dependency on the given local loader. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param resourceImportFilter the resource import filter to apply * @param resourceExportFilter the resource export filter to apply * @param classImportFilter the class import filter to apply * @param classExportFilter the class export filter to apply * @param localLoader the local loader * @param loaderPaths the set of paths that is exposed by the local loader * @return the dependency spec */ public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final LocalLoader localLoader, final Set loaderPaths) { if (importFilter == null) { throw new IllegalArgumentException("importFilter is null"); } if (exportFilter == null) { throw new IllegalArgumentException("exportFilter is null"); } if (localLoader == null) { throw new IllegalArgumentException("localLoader is null"); } if (loaderPaths == null) { throw new IllegalArgumentException("loaderPaths is null"); } if (classImportFilter == null) { throw new IllegalArgumentException("classImportFilter is null"); } if (classExportFilter == null) { throw new IllegalArgumentException("classExportFilter is null"); } if (resourceImportFilter == null) { throw new IllegalArgumentException("resourceImportFilter is null"); } if (resourceExportFilter == null) { throw new IllegalArgumentException("resourceExportFilter is null"); } return new DependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter) { Dependency getDependency(final Module module) { return new LocalDependency(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter, localLoader, loaderPaths); } public String toString() { return "dependency on local loader " + localLoader; } }; } /** * Create a dependency on the given module. * * @param identifier the module identifier * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier) { return createModuleDependencySpec(identifier, false); } /** * Create a dependency on the given module. * * @param identifier the module identifier * @param export {@code true} if the dependency should be exported by default * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier, final boolean export) { return createModuleDependencySpec(identifier, export, false); } /** * Create a dependency on the given module. * * @param identifier the module identifier * @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported * @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier, final boolean export, final boolean optional) { return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), export ? PathFilters.acceptAll() : PathFilters.rejectAll(), null, identifier, optional); } /** * Create a dependency on the given module. * * @param moduleLoader the specific module loader from which the module should be acquired * @param identifier the module identifier * @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean export) { return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), export ? PathFilters.acceptAll() : PathFilters.rejectAll(), moduleLoader, identifier, false); } /** * Create a dependency on the given module. * * @param moduleLoader the specific module loader from which the module should be acquired * @param identifier the module identifier * @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported * @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean export, final boolean optional) { return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), export ? PathFilters.acceptAll() : PathFilters.rejectAll(), moduleLoader, identifier, optional); } /** * Create a dependency on the given module. * * @param exportFilter the export filter to apply * @param identifier the module identifier * @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleIdentifier identifier, final boolean optional) { return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), exportFilter, null, identifier, optional); } /** * Create a dependency on the given module. * * @param exportFilter the export filter to apply * @param moduleLoader the specific module loader from which the module should be acquired * @param identifier the module identifier * @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) { return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), exportFilter, moduleLoader, identifier, optional); } /** * Create a dependency on the given module. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param moduleLoader the specific module loader from which the module should be acquired * @param identifier the module identifier * @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) { return createModuleDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), moduleLoader, identifier, optional); } /** * Create a dependency on the given module. * * @param importFilter the import filter to apply * @param exportFilter the export filter to apply * @param resourceImportFilter the resource import filter to apply * @param resourceExportFilter the resource export filter to apply * @param classImportFilter the class import filter to apply * @param classExportFilter the class export filter to apply * @param moduleLoader the specific module loader from which the module should be acquired * @param identifier the module identifier * @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory * @return the dependency spec */ public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) { if (importFilter == null) { throw new IllegalArgumentException("importFilter is null"); } if (exportFilter == null) { throw new IllegalArgumentException("exportFilter is null"); } if (identifier == null) { throw new IllegalArgumentException("identifier is null"); } if (classImportFilter == null) { throw new IllegalArgumentException("classImportFilter is null"); } if (classExportFilter == null) { throw new IllegalArgumentException("classExportFilter is null"); } if (resourceImportFilter == null) { throw new IllegalArgumentException("resourceImportFilter is null"); } if (resourceExportFilter == null) { throw new IllegalArgumentException("resourceExportFilter is null"); } return new ModuleDependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter, moduleLoader, identifier, optional); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/DependencyTreeViewer.java000066400000000000000000000121731257205723500303100ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * A dependency tree viewer utility. Prints out the dependency tree for a module. */ public final class DependencyTreeViewer { private static O[] filtered(Class oType, I... inputs) { final I[] newArray = Arrays.copyOf(inputs, inputs.length); int o = 0; for (int i = 0; i < inputs.length; i ++) { if (oType.getComponentType().isInstance(inputs[i])) { newArray[o++] = (O) inputs[i]; } } return Arrays.copyOf(newArray, o, oType); } private static void print(PrintWriter out, String prefix, ModuleSpec spec, FastCopyHashSet visited, File... roots) { if (spec instanceof AliasModuleSpec) { final AliasModuleSpec aliasModuleSpec = (AliasModuleSpec) spec; out.print(" -> "); final ModuleIdentifier aliasTarget = aliasModuleSpec.getAliasTarget(); out.println(aliasTarget); if (visited.add(aliasTarget)) { try { final ModuleSpec moduleSpec = LocalModuleFinder.parseModuleXmlFile(aliasTarget, null, roots); print(out, prefix, moduleSpec, visited); } catch (IOException e) { out.println(e); } catch (ModuleLoadException e) { out.println(e); } } } else if (spec instanceof ConcreteModuleSpec) { out.println(); final ConcreteModuleSpec concreteModuleSpec = (ConcreteModuleSpec) spec; final DependencySpec[] dependencies = filtered(ModuleDependencySpec[].class, concreteModuleSpec.getDependencies()); for (int i = 0, dependenciesLength = dependencies.length; i < dependenciesLength; i++) { print(out, prefix, dependencies[i], visited, i == dependenciesLength - 1, roots); } } else { out.println(); } } private static void print(PrintWriter out, String prefix, DependencySpec spec, FastCopyHashSet visited, final boolean last, final File... roots) { if (spec instanceof ModuleDependencySpec) { final ModuleDependencySpec moduleDependencySpec = (ModuleDependencySpec) spec; final ModuleIdentifier identifier = moduleDependencySpec.getIdentifier(); out.print(prefix); out.print(last ? '└' : '├'); out.print('─'); out.print(' '); out.print(identifier); if (moduleDependencySpec.isOptional()) { out.print(" (optional)"); } final PathFilter exportFilter = moduleDependencySpec.getExportFilter(); if (! exportFilter.equals(PathFilters.rejectAll())) { out.print(" (exported)"); } if (visited.add(identifier)) { print(out, prefix + (last ? " " : "│ "), identifier, visited, roots); } else { out.println(); } } } private static void print(PrintWriter out, String prefix, ModuleIdentifier identifier, FastCopyHashSet visited, final File... roots) { final ModuleSpec moduleSpec; try { moduleSpec = LocalModuleFinder.parseModuleXmlFile(identifier, null, roots); if (moduleSpec == null) { out.println(" (not found)"); } else { print(out, prefix, moduleSpec, visited, roots); } } catch (IOException e) { out.print(" ("); out.print(e); out.println(")"); } catch (ModuleLoadException e) { out.print(" ("); out.print(e); out.println(")"); } } /** * Print the dependency tree for the given module with the given module root list. * * @param out the output stream to use * @param identifier the identifier of the module to examine * @param roots the module roots to search */ public static void print(PrintWriter out, ModuleIdentifier identifier, final File... roots) { out.print(identifier); print(out, "", identifier, new FastCopyHashSet(), roots); out.flush(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FastCopyHashSet.java000066400000000000000000000373131257205723500272430ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.Serializable; import java.util.AbstractSet; import java.util.Arrays; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /** * A HashSet that is optimized for fast shallow copies. If the copy-ctor is * passed another FastCopyHashSet, or clone is called on this set, the shallow * copy can be performed using little more than a single array copy. In order to * accomplish this, immutable objects must be used internally, so update * operations result in slightly more object churn than HashSet. *

* Note: It is very important to use a smaller load factor than you normally * would for HashSet, since the implementation is open-addressed with linear * probing. With a 50% load-factor a get is expected to return in only 2 probes. * However, a 90% load-factor is expected to return in around 50 probes. * * @author Jason T. Greene * @author David M. Lloyd */ class FastCopyHashSet extends AbstractSet implements Set, Cloneable, Serializable { /** * Serialization ID */ private static final long serialVersionUID = 10929568968762L; /** * Same default as HashMap, must be a power of 2 */ private static final int DEFAULT_CAPACITY = 64; /** * MAX_INT - 1 */ private static final int MAXIMUM_CAPACITY = 1 << 30; /** * 50% */ private static final float DEFAULT_LOAD_FACTOR = 0x0.5p0f; /** * The open-addressed table */ private transient E[] table; /** * The current number of key-value pairs */ private transient int size; /** * The next resize */ private transient int threshold; /** * The user defined load factor which defines when to resize */ private final float loadFactor; /** * Counter used to detect changes made outside of an iterator */ private transient int modCount; /** * Accumulated hash code */ private transient int hashCode; public FastCopyHashSet(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Can not have a negative size table!"); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (!(loadFactor > 0F && loadFactor <= 1F)) throw new IllegalArgumentException("Load factor must be greater than 0 and less than or equal to 1"); this.loadFactor = loadFactor; init(initialCapacity, loadFactor); } public FastCopyHashSet(Set set) { if (set instanceof FastCopyHashSet) { FastCopyHashSet fast = (FastCopyHashSet) set; table = fast.table.clone(); loadFactor = fast.loadFactor; size = fast.size; threshold = fast.threshold; hashCode = fast.hashCode; } else { loadFactor = DEFAULT_LOAD_FACTOR; init(set.size(), loadFactor); addAll(set); } } @SuppressWarnings("unchecked") private void init(int initialCapacity, float loadFactor) { int c = 1; while (c < initialCapacity) c <<= 1; threshold = (int) (c * loadFactor); // Include the load factor when sizing the table for the first time if (initialCapacity > threshold && c < MAXIMUM_CAPACITY) { c <<= 1; threshold = (int) (c * loadFactor); } table = (E[]) new Object[c]; } public FastCopyHashSet(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public FastCopyHashSet() { this(DEFAULT_CAPACITY); } private int nextIndex(int index, int length) { index = (index >= length - 1) ? 0 : index + 1; return index; } private static int index(int hashCode, int length) { return hashCode & (length - 1); } public int size() { return size; } public boolean isEmpty() { return size == 0; } public boolean contains(Object key) { if (key == null) { return false; } int hash = key.hashCode(); int length = table.length; int index = index(hash, length); for (int start = index; ;) { E e = table[index]; if (e == null) return false; if (key.equals(e)) return true; index = nextIndex(index, length); if (index == start) // Full table return false; } } public boolean add(E key) { if (key == null) { throw new IllegalArgumentException("key is null"); } E[] table = this.table; int hash = key.hashCode(); int length = table.length; int index = index(hash, length); boolean f = false; for (int start = index; ;) { E e = table[index]; if (e == null) break; if (! f) { f= true; } if (key.equals(e)) { return false; } index = nextIndex(index, length); if (index == start) throw new IllegalStateException("Table is full!"); } modCount++; table[index] = key; hashCode += key.hashCode(); if (++size >= threshold) resize(length); return true; } @SuppressWarnings("unchecked") private void resize(int from) { int newLength = from << 1; // Can't get any bigger if (newLength > MAXIMUM_CAPACITY || newLength <= from) return; E[] newTable = (E[]) new Object[newLength]; E[] old = table; for (E e : old) { if (e == null) continue; int index = index(e.hashCode(), newLength); while (newTable[index] != null) index = nextIndex(index, newLength); newTable[index] = e; } threshold = (int) (loadFactor * newLength); table = newTable; } public boolean addAll(Collection set) { int size = set.size(); if (size == 0) return false; boolean changed = false; for (E e : set) { if (add(e)) { changed = true; } } return changed; } public boolean remove(Object key) { E[] table = this.table; int length = table.length; int hash = key.hashCode(); int start = index(hash, length); for (int index = start; ;) { E e = table[index]; if (e == null) return false; if (key.equals(e)) { table[index] = null; hashCode -= hash; relocate(index); modCount++; size--; return true; } index = nextIndex(index, length); if (index == start) return false; } } private void relocate(int start) { E[] table = this.table; int length = table.length; int current = nextIndex(start, length); for (; ;) { E e = table[current]; if (e == null) return; // A Doug Lea variant of Knuth's Section 6.4 Algorithm R. // This provides a non-recursive method of relocating // entries to their optimal positions once a gap is created. int prefer = index(e.hashCode(), length); if ((current < prefer && (prefer <= start || start <= current)) || (prefer <= start && start <= current)) { table[start] = e; table[current] = null; start = current; } current = nextIndex(current, length); } } public void clear() { modCount++; E[] table = this.table; for (int i = 0; i < table.length; i++) table[i] = null; size = hashCode = 0; } @SuppressWarnings("unchecked") public FastCopyHashSet clone() { try { FastCopyHashSet clone = (FastCopyHashSet) super.clone(); clone.table = table.clone(); return clone; } catch (CloneNotSupportedException e) { // should never happen throw new IllegalStateException(e); } } public Iterator iterator() { return new KeyIterator(); } public void printDebugStats() { int optimal = 0; int total = 0; int totalSkew = 0; int maxSkew = 0; for (int i = 0; i < table.length; i++) { E e = table[i]; if (e != null) { total++; int target = index(e.hashCode(), table.length); if (i == target) optimal++; else { int skew = Math.abs(i - target); if (skew > maxSkew) maxSkew = skew; totalSkew += skew; } } } System.out.println(" Size: " + size); System.out.println(" Real Size: " + total); System.out.println(" Optimal: " + optimal + " (" + (float) optimal * 100 / total + "%)"); System.out.println(" Average Distance: " + ((float) totalSkew / (total - optimal))); System.out.println(" Max Distance: " + maxSkew); } @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); int size = s.readInt(); init(size, loadFactor); for (int i = 0; i < size; i++) { E key = (E) s.readObject(); putForCreate(key); } this.size = size; } @SuppressWarnings("unchecked") private void putForCreate(E key) { E[] table = this.table; int hash = key.hashCode(); int length = table.length; int index = index(hash, length); E e = table[index]; while (e != null) { index = nextIndex(index, length); e = table[index]; } table[index] = key; } private void writeObject(java.io.ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeInt(size); for (E e : table) { if (e != null) { s.writeObject(e); } } } public boolean containsAll(final Collection c) { final E[] table = this.table; for (E e : table) { if (e != null) { if (! c.contains(e)) { return false; } } } return true; } @SuppressWarnings("NonFinalFieldReferenceInEquals") public boolean equals(final Object o) { if (o == this) return true; if (! (o instanceof Set)) return false; if (o instanceof FastCopyHashSet) { final FastCopyHashSet set = (FastCopyHashSet) o; if (hashCode != set.hashCode) { return false; } if (table.length == set.table.length) { return Arrays.equals(table, set.table); } } Set set = (Set) o; if (set.size() != size()) return false; try { return containsAll(set); } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } } @SuppressWarnings("NonFinalFieldReferencedInHashCode") public int hashCode() { return hashCode; } public Object[] getRawArray() { return table; } private class KeyIterator implements Iterator { private int next = 0; private int expectedCount = modCount; private int current = -1; private boolean hasNext; private E[] table = FastCopyHashSet.this.table; public E next() { if (modCount != expectedCount) throw new ConcurrentModificationException(); if (!hasNext && !hasNext()) throw new NoSuchElementException(); current = next++; hasNext = false; return table[current]; } public boolean hasNext() { if (hasNext == true) return true; E[] table = this.table; for (int i = next; i < table.length; i++) { if (table[i] != null) { next = i; return hasNext = true; } } next = table.length; return false; } @SuppressWarnings("unchecked") public void remove() { if (modCount != expectedCount) throw new ConcurrentModificationException(); int current = this.current; int delete = current; if (current == -1) throw new IllegalStateException(); // Invalidate current (prevents multiple remove) this.current = -1; // Start were we relocate next = delete; E[] table = this.table; if (table != FastCopyHashSet.this.table) { FastCopyHashSet.this.remove(table[delete]); table[delete] = null; expectedCount = modCount; return; } int length = table.length; int i = delete; table[delete] = null; size--; for (; ;) { i = nextIndex(i, length); E e = table[i]; if (e == null) break; int prefer = index(e.hashCode(), length); if ((i < prefer && (prefer <= delete || delete <= i)) || (prefer <= delete && delete <= i)) { // Snapshot the unseen portion of the table if we have // to relocate an entry that was already seen by this iterator if (i < current && current <= delete && table == FastCopyHashSet.this.table) { int remaining = length - current; E[] newTable = (E[]) new Object[remaining]; System.arraycopy(table, current, newTable, 0, remaining); // Replace iterator's table. // Leave table local var pointing to the real table this.table = newTable; next = 0; } // Do the swap on the real table table[delete] = e; table[i] = null; delete = i; } } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FileEntryResource.java000066400000000000000000000060431257205723500276400ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static java.security.AccessController.doPrivileged; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.UndeclaredThrowableException; import java.net.URL; import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; /** * A file entry resource. * * @author David M. Lloyd */ final class FileEntryResource implements Resource { private final String name; private final File file; private final URL url; private final AccessControlContext context; FileEntryResource(final String name, final File file, final URL url, final AccessControlContext context) { this.name = name; this.file = file; this.url = url; this.context = context; } public long getSize() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { return doPrivileged(new PrivilegedAction() { public Long run() { return Long.valueOf(file.length()); } }, context).longValue(); } else { return file.length(); } } public String getName() { return name; } public URL getURL() { return url; } public InputStream openStream() throws IOException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { return doPrivileged(new PrivilegedExceptionAction() { public FileInputStream run() throws IOException { return new FileInputStream(file); } }, context); } catch (PrivilegedActionException e) { try { throw e.getException(); } catch (RuntimeException e1) { throw e1; } catch (IOException e1) { throw e1; } catch (Exception e1) { throw new UndeclaredThrowableException(e1); } } } else { return new FileInputStream(file); } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FileResourceLoader.java000066400000000000000000000321661257205723500277520ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static java.security.AccessController.doPrivileged; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.lang.reflect.UndeclaredThrowableException; import java.net.MalformedURLException; import java.net.URL; import java.security.AccessControlContext; import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.jar.Manifest; /** * * @author David M. Lloyd */ final class FileResourceLoader extends NativeLibraryResourceLoader implements IterableResourceLoader { private final String rootName; private final Manifest manifest; private final CodeSource codeSource; private final AccessControlContext context; FileResourceLoader(final String rootName, final File root, final AccessControlContext context) { super(root); if (root == null) { throw new IllegalArgumentException("root is null"); } if (rootName == null) { throw new IllegalArgumentException("rootName is null"); } if (context == null) { throw new IllegalArgumentException("context is null"); } this.rootName = rootName; final File manifestFile = new File(root, "META-INF" + File.separatorChar + "MANIFEST.MF"); manifest = readManifestFile(manifestFile); final URL rootUrl; final SecurityManager sm = System.getSecurityManager(); if (sm != null) { rootUrl = doPrivileged(new PrivilegedAction() { public URL run() { try { return root.getAbsoluteFile().toURI().toURL(); } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid root file specified", e); } } }, context); } else try { rootUrl = root.getAbsoluteFile().toURI().toURL(); } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid root file specified", e); } this.context = context; codeSource = new CodeSource(rootUrl, (CodeSigner[])null); } private static Manifest readManifestFile(final File manifestFile) { try { return manifestFile.exists() ? new Manifest(new FileInputStream(manifestFile)) : null; } catch (IOException e) { return null; } } public String getRootName() { return rootName; } public ClassSpec getClassSpec(final String fileName) throws IOException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { return doPrivileged(new PrivilegedExceptionAction() { public ClassSpec run() throws IOException { return doGetClassSpec(fileName); } }, context); } catch (PrivilegedActionException e) { try { throw e.getException(); } catch (IOException e1) { throw e1; } catch (RuntimeException e1) { throw e1; } catch (Exception e1) { throw new UndeclaredThrowableException(e1); } } } else { return doGetClassSpec(fileName); } } private ClassSpec doGetClassSpec(final String fileName) throws IOException { final File file = new File(getRoot(), fileName); if (! file.exists()) { return null; } final long size = file.length(); final ClassSpec spec = new ClassSpec(); spec.setCodeSource(codeSource); final InputStream is = new FileInputStream(file); try { if (size <= (long) Integer.MAX_VALUE) { final int castSize = (int) size; byte[] bytes = new byte[castSize]; int a = 0, res; while ((res = is.read(bytes, a, castSize - a)) > 0) { a += res; } // done is.close(); spec.setBytes(bytes); return spec; } else { throw new IOException("Resource is too large to be a valid class file"); } } finally { StreamUtil.safeClose(is); } } public PackageSpec getPackageSpec(final String name) throws IOException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { return doPrivileged(new PrivilegedExceptionAction() { public PackageSpec run() throws IOException { return getPackageSpec(name, manifest, getRoot().toURI().toURL()); } }, context); } catch (PrivilegedActionException e) { try { throw e.getException(); } catch (IOException e1) { throw e1; } catch (RuntimeException e1) { throw e1; } catch (Exception e1) { throw new UndeclaredThrowableException(e1); } } } else { return getPackageSpec(name, manifest, getRoot().toURI().toURL()); } } public Resource getResource(final String name) { final String canonPath = PathUtils.canonicalize(PathUtils.relativize(name)); final File file = new File(getRoot(), canonPath); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { return doPrivileged(new PrivilegedAction() { public Resource run() { if (!file.exists()) { return null; } else { try { return new FileEntryResource(canonPath, file, file.toURI().toURL(), context); } catch (MalformedURLException e) { return null; } } } }, context); } else if (! file.exists()) { return null; } else { try { return new FileEntryResource(canonPath, file, file.toURI().toURL(), context); } catch (MalformedURLException e) { return null; } } } class Itr implements Iterator { private final String base; private final String[] names; private final boolean recursive; private int i = 0; private Itr nested; private Resource next; Itr(final String base, final String[] names, final boolean recursive) { assert PathUtils.isRelative(base); assert names != null && names.length > 0; this.base = base; this.names = names; this.recursive = recursive; } public boolean hasNext() { final String[] names = this.names; if (next != null) { return true; } final String base = this.base; while (i < names.length) { final String current = names[i]; final String full = base.isEmpty() ? current : base + "/" + current; final File file = new File(getRoot(), full); if (recursive && nested == null) { final String[] children = file.list(); if (children != null && children.length > 0) { nested = new Itr(full, children, recursive); } } if (nested != null) { if (nested.hasNext()) { next = nested.next(); return true; } nested = null; } i++; if (file.isFile()) { try { next = new FileEntryResource(full, file, file.toURI().toURL(), context); return true; } catch (MalformedURLException ignored) { } } } return false; } public Resource next() { if (! hasNext()) { throw new NoSuchElementException(); } try { return next; } finally { next = null; } } public void remove() { } } public Iterator iterateResources(final String startPath, final boolean recursive) { final String canonPath = PathUtils.canonicalize(PathUtils.relativize(startPath)); final File start = new File(getRoot(), canonPath); final String[] children = start.list(); if (children == null || children.length == 0) { return Collections.emptySet().iterator(); } return new Itr(canonPath, children, recursive); } public Collection getPaths() { final List index = new ArrayList(); final File indexFile = new File(getRoot().getPath() + ".index"); if (ResourceLoaders.USE_INDEXES) { // First check for an index file if (indexFile.exists()) { try { final BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(indexFile))); try { String s; while ((s = r.readLine()) != null) { index.add(s.trim()); } return index; } finally { // if exception is thrown, undo index creation r.close(); } } catch (IOException e) { index.clear(); } } } // Manually build index, starting with the root path index.add(""); buildIndex(index, getRoot(), ""); if (ResourceLoaders.WRITE_INDEXES) { // Now try to write it boolean ok = false; try { final FileOutputStream fos = new FileOutputStream(indexFile); try { final OutputStreamWriter osw = new OutputStreamWriter(fos); try { final BufferedWriter writer = new BufferedWriter(osw); try { for (String name : index) { writer.write(name); writer.write('\n'); } writer.close(); osw.close(); fos.close(); ok = true; } finally { StreamUtil.safeClose(writer); } } finally { StreamUtil.safeClose(osw); } } finally { StreamUtil.safeClose(fos); } } catch (IOException e) { // failed, ignore } finally { if (! ok) { // well, we tried... indexFile.delete(); } } } return index; } private void buildIndex(final List index, final File root, final String pathBase) { File[] files = root.listFiles(); if (files != null) for (File file : files) { if (file.isDirectory()) { index.add(pathBase + file.getName()); buildIndex(index, file, pathBase + file.getName() + "/"); } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredIterableLocalLoader.java000066400000000000000000000043071257205723500315400ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * @author David M. Lloyd */ class FilteredIterableLocalLoader implements IterableLocalLoader { private final ClassFilter classFilter; private final IterableLocalLoader originalLoader; private final PathFilter resourcePathFilter; FilteredIterableLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final IterableLocalLoader originalLoader) { this.classFilter = classFilter; this.originalLoader = originalLoader; this.resourcePathFilter = resourcePathFilter; } public Class loadClassLocal(final String name, final boolean resolve) { return classFilter.accept(name) ? originalLoader.loadClassLocal(name, resolve) : null; } public Package loadPackageLocal(final String name) { return originalLoader.loadPackageLocal(name); } public List loadResourceLocal(final String name) { return resourcePathFilter.accept(name) ? originalLoader.loadResourceLocal(name) : Collections.emptyList(); } public Iterator iterateResources(final String startPath, final boolean recursive) { return PathFilters.filtered(resourcePathFilter, originalLoader.iterateResources(startPath, recursive)); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredIterableResourceLoader.java000066400000000000000000000046771257205723500323070ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; final class FilteredIterableResourceLoader implements IterableResourceLoader { private final PathFilter filter; private final IterableResourceLoader loader; FilteredIterableResourceLoader(final PathFilter filter, final IterableResourceLoader loader) { this.filter = filter; this.loader = loader; } public String getRootName() { return loader.getRootName(); } public ClassSpec getClassSpec(final String fileName) throws IOException { final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(fileName)); return filter.accept(canonicalFileName) ? loader.getClassSpec(canonicalFileName) : null; } public PackageSpec getPackageSpec(final String name) throws IOException { return loader.getPackageSpec(PathUtils.canonicalize(PathUtils.relativize(name))); } public Resource getResource(final String name) { final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(name)); return filter.accept(canonicalFileName) ? loader.getResource(canonicalFileName) : null; } public String getLibrary(final String name) { return loader.getLibrary(PathUtils.canonicalize(PathUtils.relativize(name))); } public Collection getPaths() { return loader.getPaths(); } public Iterator iterateResources(final String startPath, final boolean recursive) { return PathFilters.filtered(filter, loader.iterateResources(PathUtils.relativize(PathUtils.canonicalize(startPath)), recursive)); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredLocalLoader.java000066400000000000000000000035761257205723500300770ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Collections; import java.util.List; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.PathFilter; /** * @author David M. Lloyd */ class FilteredLocalLoader implements LocalLoader { private final ClassFilter classFilter; private final LocalLoader originalLoader; private final PathFilter resourcePathFilter; FilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final LocalLoader originalLoader) { this.classFilter = classFilter; this.originalLoader = originalLoader; this.resourcePathFilter = resourcePathFilter; } public Class loadClassLocal(final String name, final boolean resolve) { return classFilter.accept(name) ? originalLoader.loadClassLocal(name, resolve) : null; } public Package loadPackageLocal(final String name) { return originalLoader.loadPackageLocal(name); } public List loadResourceLocal(final String name) { return resourcePathFilter.accept(name) ? originalLoader.loadResourceLocal(name) : Collections.emptyList(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredResourceLoader.java000066400000000000000000000041341257205723500306230ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.util.Collection; import org.jboss.modules.filter.PathFilter; final class FilteredResourceLoader implements ResourceLoader { private final PathFilter filter; private final ResourceLoader loader; FilteredResourceLoader(final PathFilter filter, final ResourceLoader loader) { this.filter = filter; this.loader = loader; } public String getRootName() { return loader.getRootName(); } public ClassSpec getClassSpec(final String fileName) throws IOException { final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(fileName)); return filter.accept(canonicalFileName) ? loader.getClassSpec(canonicalFileName) : null; } public PackageSpec getPackageSpec(final String name) throws IOException { return loader.getPackageSpec(PathUtils.canonicalize(PathUtils.relativize(name))); } public Resource getResource(final String name) { final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(name)); return filter.accept(canonicalFileName) ? loader.getResource(canonicalFileName) : null; } public String getLibrary(final String name) { return loader.getLibrary(PathUtils.canonicalize(PathUtils.relativize(name))); } public Collection getPaths() { return loader.getPaths(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IdentityHashSet.java000066400000000000000000000400321257205723500272740ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Array; import java.util.AbstractSet; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; /** * An identity based hash set. A number of properties apply to this set. It * compares only using object identity, it supports null entries, it allocates * little more than a single object array, and it can be copied quickly. If the * copy-ctor is passed another IdentityHashSet, or clone is called on this set, * the shallow copy can be performed using little more than a single array copy. * * Note: It is very important to use a smaller load factor than you normally * would for HashSet, since the implementation is open-addressed with linear * probing. With a 50% load-factor a get is expected to return in only 2 probes. * However, a 90% load-factor is expected to return in around 50 probes. * * @author Jason T. Greene */ class IdentityHashSet extends AbstractSet implements Set, Cloneable, Serializable { /** * Serialization ID */ private static final long serialVersionUID = 10929568968762L; /** * Same default as HashMap, must be a power of 2 */ private static final int DEFAULT_CAPACITY = 8; /** * MAX_INT - 1 */ private static final int MAXIMUM_CAPACITY = 1 << 30; /** * 67%, just like IdentityHashMap */ private static final float DEFAULT_LOAD_FACTOR = 0.67f; /** * The open-addressed table */ private transient Object[] table; /** * The current number of key-value pairs */ private transient int size; /** * The next resize */ private transient int threshold; /** * The user defined load factor which defines when to resize */ private final float loadFactor; /** * Counter used to detect changes made outside of an iterator */ private transient int modCount; public IdentityHashSet(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Can not have a negative size table!"); if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; if (!(loadFactor > 0F && loadFactor <= 1F)) throw new IllegalArgumentException("Load factor must be greater than 0 and less than or equal to 1"); this.loadFactor = loadFactor; init(initialCapacity, loadFactor); } @SuppressWarnings("unchecked") public IdentityHashSet(Set set) { if (set instanceof IdentityHashSet) { IdentityHashSet fast = (IdentityHashSet) set; table = fast.table.clone(); loadFactor = fast.loadFactor; size = fast.size; threshold = fast.threshold; } else { loadFactor = DEFAULT_LOAD_FACTOR; init(set.size(), loadFactor); addAll(set); } } private void init(int initialCapacity, float loadFactor) { int c = 1; for (; c < initialCapacity; c <<= 1); threshold = (int) (c * loadFactor); // Include the load factor when sizing the table for the first time if (initialCapacity > threshold && c < MAXIMUM_CAPACITY) { c <<= 1; threshold = (int) (c * loadFactor); } table = new Object[c]; } public IdentityHashSet(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public IdentityHashSet() { this(DEFAULT_CAPACITY); } // The normal bit spreader... private static int hash(Object o) { int h = System.identityHashCode(o); h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } private int nextIndex(int index, int length) { index = (index >= length - 1) ? 0 : index + 1; return index; } private static int index(int hashCode, int length) { return hashCode & (length - 1); } public int size() { return size; } public boolean isEmpty() { return size == 0; } public boolean contains(Object entry) { if (entry == null) return false; int hash = hash(entry); int length = table.length; int index = index(hash, length); for (int start = index;;) { Object e = table[index]; if (e == null) return false; if (entry == e) return true; index = nextIndex(index, length); if (index == start) // Full table return false; } } public boolean add(E entry) { if (entry == null) { throw new NullPointerException("entry is null"); } Object[] table = this.table; int hash = hash(entry); int length = table.length; int index = index(hash, length); for (int start = index;;) { Object e = table[index]; if (e == null) break; if (e == entry) return false; index = nextIndex(index, length); if (index == start) throw new IllegalStateException("Table is full!"); } modCount++; table[index] = entry; if (++size >= threshold) resize(length); return true; } private void resize(int from) { int newLength = from << 1; // Can't get any bigger if (newLength > MAXIMUM_CAPACITY || newLength <= from) return; Object[] newTable = new Object[newLength]; Object[] old = table; for (Object e : old) { if (e == null) continue; int index = index(hash(e), newLength); while (newTable[index] != null) index = nextIndex(index, newLength); newTable[index] = e; } threshold = (int) (loadFactor * newLength); table = newTable; } @SuppressWarnings({ "unchecked" }) public boolean addAll(Collection collection) { int size = collection.size(); if (size == 0) return false; if (size > threshold) { if (size > MAXIMUM_CAPACITY) size = MAXIMUM_CAPACITY; int length = table.length; for (; length < size; length <<= 1); resize(length); } boolean state = false; if (collection instanceof IdentityHashSet) { for (E e : ((E[]) (((IdentityHashSet) collection).table))) if (e != null) state |= add(e); } else { for (E e : collection) state |= add(e); } return state; } public boolean remove(Object o) { if (o == null) return false; Object[] table = this.table; int length = table.length; int hash = hash(o); int start = index(hash, length); for (int index = start;;) { Object e = table[index]; if (e == null) return false; if (e == o) { table[index] = null; relocate(index); modCount++; size--; return true; } index = nextIndex(index, length); if (index == start) return false; } } private void relocate(int start) { Object[] table = this.table; int length = table.length; int current = nextIndex(start, length); for (;;) { Object e = table[current]; if (e == null) return; // A Doug Lea variant of Knuth's Section 6.4 Algorithm R. // This provides a non-recursive method of relocating // entries to their optimal positions once a gap is created. int prefer = index(hash(e), length); if ((current < prefer && (prefer <= start || start <= current)) || (prefer <= start && start <= current)) { table[start] = e; table[current] = null; start = current; } current = nextIndex(current, length); } } public void clear() { modCount++; Object[] table = this.table; for (int i = 0; i < table.length; i++) table[i] = null; size = 0; } @SuppressWarnings("unchecked") public IdentityHashSet clone() { try { IdentityHashSet clone = (IdentityHashSet) super.clone(); clone.table = table.clone(); return clone; } catch (CloneNotSupportedException e) { // should never happen throw new IllegalStateException(e); } } /** * Advanced method that returns a copy of the internal table. The resulting * array will contain nulls at random places that must be skipped. In * addition, it will not operate correctly if a null was inserted into the * set. Use at your own risk.... * * @return an array containing elements in this set along with randomly * placed nulls, */ @SuppressWarnings({ "unchecked" }) public E[] toScatteredArray(E[] dummy) { final E[] ret = (E[]) Array.newInstance(dummy.getClass().getComponentType(), table.length); System.arraycopy((E[])table, 0, ret, 0, ret.length); return ret; } /** * Warning: this will crap out if the set contains a {@code null}. * * @param target the target to write to * @param offs the offset into the target * @param len the length to write * @return the target array */ @SuppressWarnings({ "unchecked" }) public E[] toArray(final E[] target, final int offs, final int len) { assert len <= size; final E[] table = (E[]) this.table; E e; final int last = offs + len; for (int i = offs, j = 0; i < last; j ++) { e = table[j]; if (e != null) { target[i++] = e; } } return target; } public void printDebugStats() { int optimal = 0; int total = 0; int totalSkew = 0; int maxSkew = 0; for (int i = 0; i < table.length; i++) { Object e = table[i]; if (e != null) { total++; int target = index(hash(e), table.length); if (i == target) optimal++; else { int skew = Math.abs(i - target); if (skew > maxSkew) maxSkew = skew; totalSkew += skew; } } } System.out.println(" Size: " + size); System.out.println(" Real Size: " + total); System.out.println(" Optimal: " + optimal + " (" + (float) optimal * 100 / total + "%)"); System.out.println(" Average Distance: " + ((float) totalSkew / (total - optimal))); System.out.println(" Max Distance: " + maxSkew); } @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); int size = s.readInt(); init(size, loadFactor); for (int i = 0; i < size; i++) { putForCreate((E) s.readObject()); } this.size = size; } private void putForCreate(E entry) { Object[] table = this.table; int hash = hash(entry); int length = table.length; int index = index(hash, length); Object e = table[index]; while (e != null) { index = nextIndex(index, length); e = table[index]; } table[index] = entry; } private void writeObject(java.io.ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeInt(size); for (Object e : table) { if (e != null) { s.writeObject(e); } } } @Override public Iterator iterator() { return new IdentityHashSetIterator(); } private class IdentityHashSetIterator implements Iterator { private int next = 0; private int expectedCount = modCount; private int current = -1; private boolean hasNext; Object table[] = IdentityHashSet.this.table; public boolean hasNext() { if (hasNext == true) return true; Object table[] = this.table; for (int i = next; i < table.length; i++) { if (table[i] != null) { next = i; return hasNext = true; } } next = table.length; return false; } @SuppressWarnings("unchecked") public E next() { if (modCount != expectedCount) throw new ConcurrentModificationException(); if (!hasNext && !hasNext()) throw new NoSuchElementException(); current = next++; hasNext = false; return (E) table[current]; } public void remove() { if (modCount != expectedCount) throw new ConcurrentModificationException(); int current = this.current; int delete = current; if (current == -1) throw new IllegalStateException(); // Invalidate current (prevents multiple remove) this.current = -1; // Start were we relocate next = delete; Object[] table = this.table; if (table != IdentityHashSet.this.table) { IdentityHashSet.this.remove(table[delete]); table[delete] = null; expectedCount = modCount; return; } int length = table.length; int i = delete; table[delete] = null; size--; for (;;) { i = nextIndex(i, length); Object e = table[i]; if (e == null) break; int prefer = index(hash(e), length); if ((i < prefer && (prefer <= delete || delete <= i)) || (prefer <= delete && delete <= i)) { // Snapshot the unseen portion of the table if we have // to relocate an entry that was already seen by this // iterator if (i < current && current <= delete && table == IdentityHashSet.this.table) { int remaining = length - current; Object[] newTable = new Object[remaining]; System.arraycopy(table, current, newTable, 0, remaining); // Replace iterator's table. // Leave table local var pointing to the real table this.table = newTable; next = 0; } // Do the swap on the real table table[delete] = e; table[i] = null; delete = i; } } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IterableLocalLoader.java000066400000000000000000000031011257205723500300500ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Iterator; /** * A local loader which can enumerate its contents. * * @author David M. Lloyd */ public interface IterableLocalLoader extends LocalLoader { /** * Enumerate all the resources under the given path. The given path name is relative to the root * of the resource loader. If the path "escapes" the root via {@code ..}, such segments will be consumed. * If the path is absolute, it will be converted to a relative path by dropping the leading {@code /}. * * @param startPath the path to search under * @param recursive {@code true} to recursively descend into subdirectories, {@code false} to only read this path * @return the resource iterator (possibly empty) */ Iterator iterateResources(String startPath, boolean recursive); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IterableModuleFinder.java000066400000000000000000000026271257205723500302600ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Iterator; /** * A module finder which is iterable. * * @author David M. Lloyd */ public interface IterableModuleFinder extends ModuleFinder { /** * Iterate the modules which can be located via this module finder. * * @param baseIdentifier the identifier to start with, or {@code null} to iterate all modules * @param recursive {@code true} to find recursively nested modules, {@code false} to only find immediately nested modules * @return an iterator for the modules in this module finder */ Iterator iterateModules(ModuleIdentifier baseIdentifier, boolean recursive); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IterableResourceLoader.java000066400000000000000000000031311257205723500306100ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Iterator; /** * A resource loader which has the ability to enumerate its contents. * * @author David M. Lloyd */ public interface IterableResourceLoader extends ResourceLoader { /** * Enumerate all the resources under the given path. The given path name is relative to the root * of the resource loader. If the path "escapes" the root via {@code ..}, such segments will be consumed. * If the path is absolute, it will be converted to a relative path by dropping the leading {@code /}. * * @param startPath the path to search under * @param recursive {@code true} to recursively descend into subdirectories, {@code false} to only read this path * @return the resource iterator (possibly empty) */ Iterator iterateResources(String startPath, boolean recursive); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JDKPaths.java000066400000000000000000000113261257205723500256370ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.IOException; import java.security.AccessController; import java.util.Collections; import java.util.Enumeration; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * A utility class which maintains the set of JDK paths. Makes certain assumptions about the disposition of the * class loader used to load JBoss Modules; thus this class should only be used when booted up via the "-jar" or "-cp" * switches. * * @author David M. Lloyd */ final class JDKPaths { static final Set JDK; static { final Set pathSet = new FastCopyHashSet(1024); final Set jarSet = new FastCopyHashSet(1024); final String sunBootClassPath = AccessController.doPrivileged(new PropertyReadAction("sun.boot.class.path")); final String javaClassPath = AccessController.doPrivileged(new PropertyReadAction("java.class.path")); processClassPathItem(sunBootClassPath, jarSet, pathSet); processClassPathItem(javaClassPath, jarSet, pathSet); pathSet.add("org/jboss/modules"); pathSet.add("org/jboss/modules/filter"); pathSet.add("org/jboss/modules/log"); pathSet.add("org/jboss/modules/management"); pathSet.add("org/jboss/modules/ref"); JDK = Collections.unmodifiableSet(pathSet); } private JDKPaths() { } private static void processClassPathItem(final String classPath, final Set jarSet, final Set pathSet) { if (classPath == null) return; int s = 0, e; do { e = classPath.indexOf(File.pathSeparatorChar, s); String item = e == -1 ? classPath.substring(s) : classPath.substring(s, e); if (! jarSet.contains(item)) { final File file = new File(item); if (file.isDirectory()) { processDirectory0(pathSet, file); } else { try { processJar(pathSet, file); } catch (IOException ex) { // ignore } } } s = e + 1; } while (e != -1); } static void processJar(final Set pathSet, final File file) throws IOException { final ZipFile zipFile = new ZipFile(file); try { final Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { final ZipEntry entry = entries.nextElement(); final String name = entry.getName(); final int lastSlash = name.lastIndexOf('/'); if (lastSlash != -1) { pathSet.add(name.substring(0, lastSlash)); } } zipFile.close(); } finally { StreamUtil.safeClose(zipFile); } } static void processDirectory0(final Set pathSet, final File file) { for (File entry : file.listFiles()) { if (entry.isDirectory()) { processDirectory1(pathSet, entry, file.getPath()); } else { final String parent = entry.getParent(); if (parent != null) pathSet.add(parent); } } } static void processDirectory1(final Set pathSet, final File file, final String pathBase) { for (File entry : file.listFiles()) { if (entry.isDirectory()) { processDirectory1(pathSet, entry, pathBase); } else { String packagePath = entry.getParent(); if (packagePath != null) { packagePath = packagePath.substring(pathBase.length()).replace('\\', '/');; if(packagePath.startsWith("/")) { packagePath = packagePath.substring(1); } pathSet.add(packagePath); } } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarEntryResource.java000066400000000000000000000032031257205723500274700ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * * @author David M. Lloyd */ final class JarEntryResource implements Resource { private final JarFile jarFile; private final JarEntry entry; private final URL resourceURL; JarEntryResource(final JarFile jarFile, final JarEntry entry, final URL resourceURL) { this.jarFile = jarFile; this.entry = entry; this.resourceURL = resourceURL; } public String getName() { return entry.getName(); } public URL getURL() { return resourceURL; } public InputStream openStream() throws IOException { return jarFile.getInputStream(entry); } public long getSize() { final long size = entry.getSize(); return size == -1 ? 0 : size; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarFileResourceLoader.java000066400000000000000000000441561257205723500304110ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLStreamHandler; import java.security.CodeSigner; import java.security.CodeSource; import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.TreeSet; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * * @author David M. Lloyd * @author Thomas.Diesler@jboss.com */ final class JarFileResourceLoader extends AbstractResourceLoader implements IterableResourceLoader { private static final String INDEX_FILE = "META-INF/PATHS.LIST"; private final JarFile jarFile; private final String rootName; private final URL rootUrl; private final String relativePath; private final File fileOfJar; // protected by {@code this} private final Map codeSources = new HashMap<>(); JarFileResourceLoader(final String rootName, final JarFile jarFile) { this(rootName, jarFile, null); } JarFileResourceLoader(final String rootName, final JarFile jarFile, final String relativePath) { if (jarFile == null) { throw new IllegalArgumentException("jarFile is null"); } if (rootName == null) { throw new IllegalArgumentException("rootName is null"); } fileOfJar = new File(jarFile.getName()); this.jarFile = jarFile; this.rootName = rootName; final String realPath = relativePath == null ? null : PathUtils.canonicalize(relativePath); this.relativePath = realPath; try { rootUrl = getJarURI(fileOfJar.toURI(), realPath).toURL(); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid root file specified", e); } catch (MalformedURLException e) { throw new IllegalArgumentException("Invalid root file specified", e); } } private static URI getJarURI(final URI original, final String nestedPath) throws URISyntaxException { final StringBuilder b = new StringBuilder(); b.append("file:"); assert original.getScheme().equals("file"); final String path = original.getPath(); assert path != null; final String host = original.getHost(); if (host != null) { final String userInfo = original.getRawUserInfo(); b.append("//"); if (userInfo != null) { b.append(userInfo).append('@'); } b.append(host); } b.append(path).append("!/"); if (nestedPath != null) { b.append(nestedPath); } return new URI("jar", b.toString(), null); } public String getRootName() { return rootName; } public synchronized ClassSpec getClassSpec(final String fileName) throws IOException { final ClassSpec spec = new ClassSpec(); final JarEntry entry = getJarEntry(fileName); if (entry == null) { // no such entry return null; } final long size = entry.getSize(); final InputStream is = jarFile.getInputStream(entry); try { if (size == -1) { // size unknown final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final byte[] buf = new byte[16384]; int res; while ((res = is.read(buf)) > 0) { baos.write(buf, 0, res); } // done CodeSource codeSource = createCodeSource(entry); baos.close(); is.close(); spec.setBytes(baos.toByteArray()); spec.setCodeSource(codeSource); return spec; } else if (size <= (long) Integer.MAX_VALUE) { final int castSize = (int) size; byte[] bytes = new byte[castSize]; int a = 0, res; while ((res = is.read(bytes, a, castSize - a)) > 0) { a += res; } // consume remainder so that cert check doesn't fail in case of wonky JARs while (is.read() != -1); // done CodeSource codeSource = createCodeSource(entry); is.close(); spec.setBytes(bytes); spec.setCodeSource(codeSource); return spec; } else { throw new IOException("Resource is too large to be a valid class file"); } } finally { StreamUtil.safeClose(is); } } // this MUST only be called after the input stream is fully read (see MODULES-201) private CodeSource createCodeSource(final JarEntry entry) { final CodeSigner[] entryCodeSigners = entry.getCodeSigners(); final CodeSigners codeSigners = entryCodeSigners == null || entryCodeSigners.length == 0 ? EMPTY_CODE_SIGNERS : new CodeSigners(entryCodeSigners); CodeSource codeSource = codeSources.get(codeSigners); if (codeSource == null) { codeSources.put(codeSigners, codeSource = new CodeSource(rootUrl, entryCodeSigners)); } return codeSource; } private JarEntry getJarEntry(final String fileName) { return relativePath == null ? jarFile.getJarEntry(fileName) : jarFile.getJarEntry(relativePath + "/" + fileName); } public PackageSpec getPackageSpec(final String name) throws IOException { final Manifest manifest; if (relativePath == null) { manifest = jarFile.getManifest(); } else { JarEntry jarEntry = getJarEntry("META-INF/MANIFEST.MF"); if (jarEntry == null) { manifest = null; } else { InputStream inputStream = jarFile.getInputStream(jarEntry); try { manifest = new Manifest(inputStream); } finally { StreamUtil.safeClose(inputStream); } } } return getPackageSpec(name, manifest, rootUrl); } public String getLibrary(final String name) { // JARs cannot have libraries in them return null; } public Resource getResource(String name) { try { final JarFile jarFile = this.jarFile; name = PathUtils.canonicalize(PathUtils.relativize(name)); final JarEntry entry = getJarEntry(name); if (entry == null) { return null; } final URI uri; try { File absoluteFile = new File(jarFile.getName()).getAbsoluteFile(); String path = absoluteFile.getPath(); path = PathUtils.canonicalize(path); if (File.separatorChar != '/') { // optimizes away on platforms with / path = path.replace(File.separatorChar, '/'); } if (PathUtils.isRelative(path)) { // should not be possible, but the JDK thinks this might happen sometimes..? path = "/" + path; } if (path.startsWith("//")) { // UNC path URIs have loads of leading slashes path = "//" + path; } uri = new URI("file", null, path, null); } catch (URISyntaxException x) { throw new IllegalStateException(x); } return new JarEntryResource(jarFile, entry, new URL(null, getJarURI(uri, entry.getName()).toString(), (URLStreamHandler) null)); } catch (MalformedURLException e) { // must be invalid...? (todo: check this out) return null; } catch (URISyntaxException e) { // must be invalid...? (todo: check this out) return null; } } public Iterator iterateResources(final String startPath, final boolean recursive) { final JarFile jarFile = this.jarFile; final String startName = PathUtils.canonicalize(PathUtils.relativize(startPath)); final Enumeration entries = jarFile.entries(); return new Iterator() { private Resource next; public boolean hasNext() { while (next == null) { if (! entries.hasMoreElements()) { return false; } final JarEntry entry = entries.nextElement(); final String name = entry.getName(); if ((recursive ? PathUtils.isChild(startName, name) : PathUtils.isDirectChild(startName, name))) { if (!entry.isDirectory()) { try { next = new JarEntryResource(jarFile, entry, getJarURI(new File(jarFile.getName()).toURI(), entry.getName()).toURL()); } catch (Exception ignored) { } } } } return true; } public Resource next() { if (! hasNext()) { throw new NoSuchElementException(); } try { return next; } finally { next = null; } } public void remove() { throw new UnsupportedOperationException(); } }; } public Collection getPaths() { final Collection index = new HashSet(); index.add(""); String relativePath = this.relativePath; // First check for an external index final JarFile jarFile = this.jarFile; final String jarFileName = jarFile.getName(); final long jarModified = fileOfJar.lastModified(); final File indexFile = new File(jarFileName + ".index"); if (ResourceLoaders.USE_INDEXES) { if (indexFile.exists()) { final long indexModified = indexFile.lastModified(); if (indexModified != 0L && jarModified != 0L && indexModified >= jarModified) try { return readIndex(new FileInputStream(indexFile), index, relativePath); } catch (IOException e) { index.clear(); } } } // Next check for an internal index JarEntry listEntry = jarFile.getJarEntry(INDEX_FILE); if (listEntry != null) { try { return readIndex(jarFile.getInputStream(listEntry), index, relativePath); } catch (IOException e) { index.clear(); } } // Next just read the JAR extractJarPaths(jarFile, relativePath, index); if (ResourceLoaders.WRITE_INDEXES && relativePath == null) { writeExternalIndex(indexFile, index); } return index; } static void extractJarPaths(final JarFile jarFile, String relativePath, final Collection index) { index.add(""); final Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { final JarEntry jarEntry = entries.nextElement(); final String name = jarEntry.getName(); final int idx = name.lastIndexOf('/'); if (idx == -1) continue; final String path = name.substring(0, idx); if (path.length() == 0 || path.endsWith("/")) { // invalid name, just skip... continue; } if (relativePath == null) { index.add(path); } else { if (path.startsWith(relativePath + "/")) { index.add(path.substring(relativePath.length() + 1)); } } } } static void writeExternalIndex(final File indexFile, final Collection index) { // Now try to write it boolean ok = false; try { final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexFile))); try { for (String name : index) { writer.write(name); writer.write('\n'); } writer.close(); ok = true; } finally { StreamUtil.safeClose(writer); } } catch (IOException e) { // failed, ignore } finally { if (! ok) { // well, we tried... indexFile.delete(); } } } static Collection readIndex(final InputStream stream, final Collection index, final String relativePath) throws IOException { final BufferedReader r = new BufferedReader(new InputStreamReader(stream)); try { String s; while ((s = r.readLine()) != null) { String name = s.trim(); if (relativePath == null) { index.add(name); } else { if (name.startsWith(relativePath + "/")) { index.add(name.substring(relativePath.length() + 1)); } } } return index; } finally { // if exception is thrown, undo index creation r.close(); } } static void addInternalIndex(File file, boolean modify) throws IOException { final JarFile oldJarFile = new JarFile(file, false); try { final Collection index = new TreeSet(); final File outputFile; outputFile = new File(file.getAbsolutePath().replace(".jar", "-indexed.jar")); final ZipOutputStream zo = new ZipOutputStream(new FileOutputStream(outputFile)); try { Enumeration entries = oldJarFile.entries(); while (entries.hasMoreElements()) { final JarEntry entry = entries.nextElement(); // copy data, unless we're replacing the index if (!entry.getName().equals(INDEX_FILE)) { final JarEntry clone = (JarEntry) entry.clone(); // Compression level and format can vary across implementations if (clone.getMethod() != ZipEntry.STORED) clone.setCompressedSize(-1); zo.putNextEntry(clone); StreamUtil.copy(oldJarFile.getInputStream(entry), zo); } // add to the index final String name = entry.getName(); final int idx = name.lastIndexOf('/'); if (idx == -1) continue; final String path = name.substring(0, idx); if (path.length() == 0 || path.endsWith("/")) { // invalid name, just skip... continue; } index.add(path); } // write index zo.putNextEntry(new ZipEntry(INDEX_FILE)); final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zo)); try { for (String name : index) { writer.write(name); writer.write('\n'); } writer.close(); } finally { StreamUtil.safeClose(writer); } zo.close(); oldJarFile.close(); if (modify) { file.delete(); if (!outputFile.renameTo(file)) { throw new IOException("failed to rename " + outputFile.getAbsolutePath() + " to " + file.getAbsolutePath()); } } } finally { StreamUtil.safeClose(zo); } } finally { StreamUtil.safeClose(oldJarFile); } } private static final CodeSigners EMPTY_CODE_SIGNERS = new CodeSigners(new CodeSigner[0]); static final class CodeSigners { private final CodeSigner[] codeSigners; private final int hashCode; public CodeSigners(final CodeSigner[] codeSigners) { this.codeSigners = codeSigners; hashCode = Arrays.hashCode(codeSigners); } public boolean equals(final Object obj) { return obj instanceof CodeSigners && equals((CodeSigners) obj); } private boolean equals(final CodeSigners other) { return Arrays.equals(codeSigners, other.codeSigners); } public int hashCode() { return hashCode; } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarModuleFinder.java000077500000000000000000000162341257205723500272470ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.security.AccessControlContext; import java.security.AccessController; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import org.jboss.modules.filter.MultiplePathFilterBuilder; import org.jboss.modules.filter.PathFilters; /** * A module finder which uses a JAR file as a module repository. * * @author David M. Lloyd */ public final class JarModuleFinder implements ModuleFinder { private final ModuleIdentifier myIdentifier; private final JarFile jarFile; private final AccessControlContext context; /** * Construct a new instance. * * @param myIdentifier the identifier to use for the JAR itself * @param jarFile the JAR file to encapsulate */ public JarModuleFinder(final ModuleIdentifier myIdentifier, final JarFile jarFile) { this.myIdentifier = myIdentifier; this.jarFile = jarFile; context = AccessController.getContext(); } public ModuleSpec findModule(final ModuleIdentifier identifier, final ModuleLoader delegateLoader) throws ModuleLoadException { if (identifier.equals(myIdentifier)) { // special root JAR module Manifest manifest; try { manifest = jarFile.getManifest(); } catch (IOException e) { throw new ModuleLoadException("Failed to load MANIFEST from JAR", e); } ModuleSpec.Builder builder = ModuleSpec.build(identifier); Attributes mainAttributes = manifest.getMainAttributes(); String mainClass = mainAttributes.getValue(Attributes.Name.MAIN_CLASS); if (mainClass != null) { builder.setMainClass(mainClass); } String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH); String dependencies = mainAttributes.getValue("Dependencies"); MultiplePathFilterBuilder pathFilterBuilder = PathFilters.multiplePathFilterBuilder(true); pathFilterBuilder.addFilter(PathFilters.is("modules"), false); pathFilterBuilder.addFilter(PathFilters.isChildOf("modules"), false); builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new JarFileResourceLoader("", jarFile), pathFilterBuilder.create())); String[] classPathEntries = classPath == null ? JarModuleLoader.NO_STRINGS : classPath.split("\\s+"); for (String entry : classPathEntries) { if (! entry.isEmpty()) { if (entry.startsWith("../") || entry.startsWith("./") || entry.startsWith("/") || entry.contains("/../")) { // invalid continue; } if (entry.endsWith("/")) { // directory reference File root = new File(jarFile.getName(), entry); FileResourceLoader resourceLoader = new FileResourceLoader(entry, root, context); builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader)); } else { // assume a JAR File root = new File(jarFile.getName(), entry); JarFile childJarFile; try { childJarFile = new JarFile(root, true); } catch (IOException e) { // ignore and continue continue; } builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new JarFileResourceLoader(entry, childJarFile))); } } } String[] dependencyEntries = dependencies == null ? JarModuleLoader.NO_STRINGS : dependencies.split("\\s*,\\s*"); for (String dependencyEntry : dependencyEntries) { boolean optional = false; boolean export = false; dependencyEntry = dependencyEntry.trim(); if (! dependencyEntry.isEmpty()) { String[] fields = dependencyEntry.split("\\s+"); if (fields.length < 1) { continue; } String moduleName = fields[0]; for (int i = 1; i < fields.length; i++) { String field = fields[i]; if (field.equals("optional")) { optional = true; } else if (field.equals("export")) { export = true; } // else ignored } builder.addDependency(DependencySpec.createModuleDependencySpec(ModuleIdentifier.fromString(moduleName), export, optional)); } } builder.addDependency(DependencySpec.createSystemDependencySpec(JDKPaths.JDK)); builder.addDependency(DependencySpec.createLocalDependencySpec()); return builder.create(); } else { String namePath = identifier.getName().replace('.', '/'); String basePath = "modules/" + namePath + "/" + identifier.getSlot(); JarEntry moduleXmlEntry = jarFile.getJarEntry(basePath + "/module.xml"); if (moduleXmlEntry == null) { return null; } ModuleSpec moduleSpec; try { InputStream inputStream = jarFile.getInputStream(moduleXmlEntry); try { moduleSpec = ModuleXmlParser.parseModuleXml(new ModuleXmlParser.ResourceRootFactory() { public ResourceLoader createResourceLoader(final String rootPath, final String loaderPath, final String loaderName) throws IOException { return new JarFileResourceLoader(loaderName, jarFile, loaderPath); } }, basePath, inputStream, moduleXmlEntry.getName(), delegateLoader, identifier); } finally { StreamUtil.safeClose(inputStream); } } catch (IOException e) { throw new ModuleLoadException("Failed to read module.xml file", e); } return moduleSpec; } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarModuleLoader.java000066400000000000000000000043101257205723500272330ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.util.jar.JarFile; /** * @author David M. Lloyd */ final class JarModuleLoader extends ModuleLoader { static final String[] NO_STRINGS = new String[0]; private final ModuleLoader delegate; private final JarFile jarFile; private final ModuleIdentifier myIdentifier; JarModuleLoader(final ModuleLoader delegate, final JarFile jarFile) { super(new ModuleFinder[] { new JarModuleFinder(simpleNameOf(jarFile), jarFile) }); this.delegate = delegate; this.jarFile = jarFile; myIdentifier = simpleNameOf(jarFile); } private static ModuleIdentifier simpleNameOf(JarFile jarFile) { String jarName = jarFile.getName(); String simpleJarName = jarName.substring(jarName.lastIndexOf(File.separatorChar) + 1); return ModuleIdentifier.create(simpleJarName); } protected Module preloadModule(final ModuleIdentifier identifier) throws ModuleLoadException { if (identifier.equals(myIdentifier)) { return loadModuleLocal(identifier); } else { Module module = loadModuleLocal(identifier); if (module == null) { return preloadModule(identifier, delegate); } else { return module; } } } ModuleIdentifier getMyIdentifier() { return myIdentifier; } public String toString() { return "JAR module loader"; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LayeredModulePathFactory.java000066400000000000000000000221361257205723500311300ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; /** * Provides a module path that includes entries for any "layer" and "add-on" directory structures found * within the regular items in the provided module path. * * @author Brian Stansberry (c) 2012 Red Hat Inc. */ class LayeredModulePathFactory { /** * Inspects each element in the given {@code modulePath} to see if it includes a {@code layers.conf} file * and/or a standard directory structure with child directories {@code system/layers} and, optionally, * {@code system/add-ons}. If so, the layers identified in {@code layers.conf} are added to the module path * * @param modulePath the filesystem locations that make up the standard module path, each of which is to be * checked for the presence of layers and add-ons * * @return a new module path, including any layers and add-ons, if found */ static File[] resolveLayeredModulePath(File... modulePath) { boolean foundLayers = false; List layeredPath = new ArrayList(); for (File file : modulePath) { // Always add the root, as the user may place modules directly in it layeredPath.add(file); LayersConfig layersConfig = getLayersConfig(file); File layersDir = new File(file, layersConfig.getLayersPath()); if (!layersDir.exists()) { if (layersConfig.isConfigured()) { // Bad config from user throw new IllegalStateException("No layers directory found at " + layersDir); } // else this isn't a root that has layers and add-ons continue; } boolean validLayers = true; List layerFiles = new ArrayList(); for (String layerName : layersConfig.getLayers()) { File layer = new File(layersDir, layerName); if (!layer.exists()) { if (layersConfig.isConfigured()) { // Bad config from user throw new IllegalStateException(String.format("Cannot find layer %s under directory %s", layerName, layersDir)); } // else this isn't a standard layers and add-ons structure validLayers = false; break; } loadOverlays(layer, layerFiles); } if (validLayers) { foundLayers = true; layeredPath.addAll(layerFiles); // Now add-ons File[] addOns = new File(file, layersConfig.getAddOnsPath()).listFiles(); if (addOns != null) { for (File addOn : addOns) { if (addOn.isDirectory()) { loadOverlays(addOn, layeredPath); } } } } } return foundLayers ? layeredPath.toArray(new File[layeredPath.size()]) : modulePath; } private static LayersConfig getLayersConfig(File repoRoot) { File layersList = new File(repoRoot, "layers.conf"); if (!layersList.exists()) { return new LayersConfig(); } Reader reader = null; try { reader = new InputStreamReader(new FileInputStream(layersList), "UTF-8"); Properties props = new Properties(); props.load(reader); return new LayersConfig(props); } catch (IOException e) { throw new RuntimeException(e); } finally { StreamUtil.safeClose(reader); } } private static class LayersConfig { private static final String DEFAULT_LAYERS_PATH = "system/layers"; private static final String DEFAULT_ADD_ONS_PATH = "system/add-ons"; private final boolean configured; private final String layersPath; private final String addOnsPath; private final List layers; private LayersConfig() { configured = false; layersPath = DEFAULT_LAYERS_PATH; addOnsPath = DEFAULT_ADD_ONS_PATH; layers = Collections.singletonList("base"); } private LayersConfig(Properties properties) { configured = true; // Possible future enhancement; probably better to use an xml file // layersPath = properties.getProperty("layers.path", DEFAULT_LAYERS_PATH); // addOnsPath = properties.getProperty("add-ons.path", DEFAULT_ADD_ONS_PATH); // boolean excludeBase = Boolean.valueOf(properties.getProperty("exclude.base.layer", "false")); layersPath = DEFAULT_LAYERS_PATH; addOnsPath = DEFAULT_ADD_ONS_PATH; boolean excludeBase = false; String layersProp = (String) properties.get("layers"); if (layersProp == null || (layersProp = layersProp.trim()).length() == 0) { if (excludeBase) { layers = Collections.emptyList(); } else { layers = Collections.singletonList("base"); } } else { String[] layerNames = layersProp.split(","); layers = new ArrayList(); boolean hasBase = false; for (String layerName : layerNames) { if ("base".equals(layerName)) { hasBase = true; } layers.add(layerName); } if (!hasBase && !excludeBase) { layers.add("base"); } } } boolean isConfigured() { return configured; } String getLayersPath() { return layersPath; } String getAddOnsPath() { return addOnsPath; } List getLayers() { return layers; } } private static final String OVERLAYS = ".overlays"; /** * Load the overlays for each layer. * * @param layeringRoot the layer root * @param path the module path */ static void loadOverlays(final File layeringRoot, final List path) { final File overlays = new File(layeringRoot, OVERLAYS); if (overlays.exists()) { final File refs = new File(overlays, OVERLAYS); if (refs.exists()) { try { for (final String overlay : readRefs(refs)) { final File root = new File(overlays, overlay); path.add(root); } } catch (IOException e) { throw new RuntimeException(e); } } } path.add(layeringRoot); } public static List readRefs(final File file) throws IOException { if(! file.exists()) { return Collections.emptyList(); } final InputStream is = new FileInputStream(file); try { return readRefs(is); } finally { if (is != null) try { is.close(); } catch (Exception e) { throw new RuntimeException(e); } } } static List readRefs(final InputStream is) throws IOException { final List refs = new ArrayList(); final StringBuffer buffer = new StringBuffer(); do { if(buffer.length() > 0) { final String ref = buffer.toString().trim(); if(ref.length() > 0) { refs.add(ref); } } } while(readLine(is, buffer)); return refs; } static boolean readLine(InputStream is, StringBuffer buffer) throws IOException { buffer.setLength(0); int c; for(;;) { c = is.read(); switch(c) { case '\t': case '\r': break; case -1: return false; case '\n': return true; default: buffer.append((char) c); } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Linkage.java000066400000000000000000000045701257205723500256040ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Collections; import java.util.List; import java.util.Map; /** * The linkage state of a module. * * @author David M. Lloyd */ final class Linkage { private static final Dependency[] NO_DEPENDENCIES = new Dependency[0]; private static final DependencySpec[] NO_DEPENDENCY_SPECS = new DependencySpec[0]; enum State { NEW, UNLINKED, LINKING, LINKED, ; } private final DependencySpec[] dependencySpecs; private final Dependency[] dependencies; private final State state; private final Map> allPaths; Linkage(final State state) { this(NO_DEPENDENCY_SPECS, NO_DEPENDENCIES, state, Collections.>emptyMap()); } Linkage(final DependencySpec[] dependencySpecs, final Dependency[] dependencies, final State state) { this(dependencySpecs, dependencies, state, Collections.>emptyMap()); } Linkage(final DependencySpec[] dependencySpecs, final Dependency[] dependencies, final State state, final Map> allPaths) { this.dependencySpecs = dependencySpecs; this.dependencies = dependencies; this.state = state; this.allPaths = allPaths; } Map> getPaths() { return allPaths; } State getState() { return state; } Dependency[] getDependencies() { return dependencies; } DependencySpec[] getDependencySpecs() { return dependencySpecs; } static final Linkage NONE = new Linkage(State.NEW); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalDependency.java000066400000000000000000000033401257205723500272550ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Set; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.PathFilter; /** * @author David M. Lloyd */ final class LocalDependency extends Dependency { private final LocalLoader localLoader; private final Set paths; LocalDependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter, final LocalLoader localLoader, final Set paths) { super(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter); this.localLoader = localLoader; this.paths = paths; } LocalLoader getLocalLoader() { return localLoader; } Set getPaths() { return paths; } public String toString() { return "dependency on " + localLoader; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalLoader.java000066400000000000000000000041121257205723500264030ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.List; /** * A loader which implements the local part of a module. *

* Thread safety warning! The loader must never call into a class loader (or any other object) which may * take locks and subsequently delegate to a module class loader. This will cause deadlocks and other hard-to-debug * concurrency problems. * * @author David M. Lloyd */ public interface LocalLoader { /** * Load a class which is locally defined by this loader. * * @param name the class name * @param resolve {@code true} to resolve the class * @return the class, or {@code null} if there is no local class with this name */ Class loadClassLocal(String name, boolean resolve); /** * Load a package which is locally defined by this loader. * * @param name the package name * @return the package, or {@code null} if there is no local package with this name */ Package loadPackageLocal(String name); /** * Load a resource which is locally defined by this loader. The given name is a path separated * by "{@code /}" characters. * * @param name the resource path * @return the resource or resources, or an empty list if there is no local resource with this name */ List loadResourceLocal(String name); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalLoaders.java000066400000000000000000000077441257205723500266040ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.ClassFilters; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * Static factory methods for various types of local loaders. * * @apiviz.exclude * * @author David M. Lloyd */ public final class LocalLoaders { private LocalLoaders() { } /** * Create a filtered local loader. * * @param pathFilter the path filter to apply to resources * @param originalLoader the original loader * @return the filtered loader */ public static LocalLoader createPathFilteredLocalLoader(final PathFilter pathFilter, final LocalLoader originalLoader) { return new FilteredLocalLoader(ClassFilters.acceptAll(), pathFilter, originalLoader); } /** * Create a filtered local loader. * * @param pathFilter the path filter to apply to resources * @param originalLoader the original loader * @return the filtered loader */ public static IterableLocalLoader createIterablePathFilteredLocalLoader(final PathFilter pathFilter, final IterableLocalLoader originalLoader) { return new FilteredIterableLocalLoader(ClassFilters.acceptAll(), pathFilter, originalLoader); } /** * Create a filtered local loader. * * @param classFilter the class filter to apply to classes * @param originalLoader the original loader * @return the filtered loader */ public static LocalLoader createClassFilteredLocalLoader(final ClassFilter classFilter, final LocalLoader originalLoader) { return new FilteredLocalLoader(classFilter, PathFilters.acceptAll(), originalLoader); } /** * Create a filtered local loader. * * @param classFilter the class filter to apply to classes * @param originalLoader the original loader * @return the filtered loader */ public static IterableLocalLoader createIterableClassFilteredLocalLoader(final ClassFilter classFilter, final IterableLocalLoader originalLoader) { return new FilteredIterableLocalLoader(classFilter, PathFilters.acceptAll(), originalLoader); } /** * Create a filtered local loader. * * @param classFilter the class filter to apply to classes * @param resourcePathFilter the path filter to apply to resources * @param originalLoader the original loader * @return the filtered loader */ public static LocalLoader createFilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final LocalLoader originalLoader) { return new FilteredLocalLoader(classFilter, resourcePathFilter, originalLoader); } /** * Create a filtered local loader. * * @param classFilter the class filter to apply to classes * @param resourcePathFilter the path filter to apply to resources * @param originalLoader the original loader * @return the filtered loader */ public static IterableLocalLoader createIterableFilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final IterableLocalLoader originalLoader) { return new FilteredIterableLocalLoader(classFilter, resourcePathFilter, originalLoader); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalModuleFinder.java000066400000000000000000000221251257205723500275560ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.FilePermission; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import static java.security.AccessController.doPrivileged; import static java.security.AccessController.getContext; /** * A module finder which locates module specifications which are stored in a local module * repository on the filesystem, which uses {@code module.xml} descriptors. * * @author David M. Lloyd */ public final class LocalModuleFinder implements ModuleFinder { private static final File[] NO_FILES = new File[0]; private final File[] repoRoots; private final PathFilter pathFilter; private final AccessControlContext accessControlContext; private LocalModuleFinder(final File[] repoRoots, final PathFilter pathFilter, final boolean cloneRoots) { this.repoRoots = cloneRoots && repoRoots.length > 0 ? repoRoots.clone() : repoRoots; final SecurityManager sm = System.getSecurityManager(); if (sm != null) { for (File repoRoot : this.repoRoots) { if (repoRoot == null) sm.checkPermission(new FilePermission(new File(repoRoot, "-").getPath(), "read")); } } this.pathFilter = pathFilter; this.accessControlContext = AccessController.getContext(); } /** * Construct a new instance. * * @param repoRoots the repository roots to use * @param pathFilter the path filter to use */ public LocalModuleFinder(final File[] repoRoots, final PathFilter pathFilter) { this(repoRoots, pathFilter, true); } /** * Construct a new instance. * * @param repoRoots the repository roots to use */ public LocalModuleFinder(final File[] repoRoots) { this(repoRoots, PathFilters.acceptAll()); } /** * Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable * to get the list of module repository roots. *

* This is equivalent to a call to {@link LocalModuleFinder#LocalModuleFinder(boolean) LocalModuleFinder(true)}. *

*/ public LocalModuleFinder() { this(true); } /** * Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable * to get the list of module repository roots. * * @param supportLayersAndAddOns {@code true} if the identified module repository roots should be checked for * an internal structure of child "layer" and "add-on" directories that may also * be treated as module roots lower in precedence than the parent root. Any "layers" * subdirectories whose names are specified in a {@code layers.conf} file found in * the module repository root will be added in the precedence of order specified * in the {@code layers.conf} file; all "add-on" subdirectories will be added at * a lower precedence than all "layers" and with no guaranteed precedence order * between them. If {@code false} no check for "layer" and "add-on" directories * will be performed. * */ public LocalModuleFinder(boolean supportLayersAndAddOns) { this(getRepoRoots(supportLayersAndAddOns), PathFilters.acceptAll(), false); } static File[] getRepoRoots(final boolean supportLayersAndAddOns) { return supportLayersAndAddOns ? LayeredModulePathFactory.resolveLayeredModulePath(getModulePathFiles()) : getModulePathFiles(); } private static File[] getModulePathFiles() { return getFiles(System.getProperty("module.path", System.getenv("JAVA_MODULEPATH")), 0, 0); } private static File[] getFiles(final String modulePath, final int stringIdx, final int arrayIdx) { if (modulePath == null) return NO_FILES; final int i = modulePath.indexOf(File.pathSeparatorChar, stringIdx); final File[] files; if (i == -1) { files = new File[arrayIdx + 1]; files[arrayIdx] = new File(modulePath.substring(stringIdx)).getAbsoluteFile(); } else { files = getFiles(modulePath, i + 1, arrayIdx + 1); files[arrayIdx] = new File(modulePath.substring(stringIdx, i)).getAbsoluteFile(); } return files; } private static String toPathString(ModuleIdentifier moduleIdentifier) { final StringBuilder builder = new StringBuilder(40); builder.append(moduleIdentifier.getName().replace('.', File.separatorChar)); builder.append(File.separatorChar).append(moduleIdentifier.getSlot()); builder.append(File.separatorChar); return builder.toString(); } public ModuleSpec findModule(final ModuleIdentifier identifier, final ModuleLoader delegateLoader) throws ModuleLoadException { final String child = toPathString(identifier); if (pathFilter.accept(child)) { try { return doPrivileged(new PrivilegedExceptionAction() { public ModuleSpec run() throws Exception { for (File root : repoRoots) { final File file = new File(root, child); final File moduleXml = new File(file, "module.xml"); if (moduleXml.exists()) { final ModuleSpec spec = ModuleXmlParser.parseModuleXml(delegateLoader, identifier, file, moduleXml, accessControlContext); if (spec == null) break; return spec; } } return null; } }, accessControlContext); } catch (PrivilegedActionException e) { try { throw e.getException(); } catch (RuntimeException e1) { throw e1; } catch (ModuleLoadException e1) { throw e1; } catch (Error e1) { throw e1; } catch (Exception e1) { throw new UndeclaredThrowableException(e1); } } } return null; } /** * Parse a {@code module.xml} file and return the corresponding module specification. * * @param identifier the identifier to load * @param delegateLoader the delegate module loader to use for module specifications * @param roots the repository root paths to search * @return the module specification * @throws IOException if reading the module file failed * @throws ModuleLoadException if creating the module specification failed (e.g. due to a parse error) */ public static ModuleSpec parseModuleXmlFile(final ModuleIdentifier identifier, final ModuleLoader delegateLoader, final File... roots) throws IOException, ModuleLoadException { final String child = toPathString(identifier); for (File root : roots) { final File file = new File(root, child); final File moduleXml = new File(file, "module.xml"); if (moduleXml.exists()) { final ModuleSpec spec = ModuleXmlParser.parseModuleXml(delegateLoader, identifier, file, moduleXml, getContext()); if (spec == null) break; return spec; } } return null; } public String toString() { final StringBuilder b = new StringBuilder(); b.append("local module finder @").append(Integer.toHexString(hashCode())).append(" (roots: "); final int repoRootsLength = repoRoots.length; for (int i = 0; i < repoRootsLength; i++) { final File root = repoRoots[i]; b.append(root); if (i != repoRootsLength - 1) { b.append(','); } } b.append(')'); return b.toString(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalModuleLoader.java000066400000000000000000000043271257205723500275610ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * A local filesystem-backed module loader. * * @author John Bailey * @author David M. Lloyd */ public final class LocalModuleLoader extends ModuleLoader { /** * Construct a new instance. * * @param repoRoots the array of repository roots to look for modules */ public LocalModuleLoader(final File[] repoRoots) { this(repoRoots, PathFilters.acceptAll()); } /** * Construct a new instance. * * @param repoRoots the array of repository roots to look for modules * @param pathFilter the path filter to apply to roots */ public LocalModuleLoader(final File[] repoRoots, final PathFilter pathFilter) { super(new ModuleFinder[] { new LocalModuleFinder(repoRoots, pathFilter)}); } /** * Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable * to get the list of module repository roots. */ public LocalModuleLoader() { super(new ModuleFinder[] { new LocalModuleFinder() }); } public String toString() { final StringBuilder b = new StringBuilder(); b.append("local module loader @").append(Integer.toHexString(hashCode())).append(" (finder: ").append(getFinders()[0]).append(')'); return b.toString(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Main.java000066400000000000000000000614071257205723500251200ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import __redirected.__JAXPRedirected; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.lang.management.ManagementFactory; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.security.Policy; import java.util.Enumeration; import java.util.Iterator; import java.util.ServiceLoader; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.logging.LogManager; import java.util.jar.Manifest; import java.util.prefs.Preferences; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jboss.modules.log.JDKModuleLogger; import static java.security.AccessController.doPrivileged; import static org.jboss.modules.SecurityActions.setContextClassLoader; /** * The main entry point of JBoss Modules when run as a JAR on the command line. * * @author David M. Lloyd * @author Jason T. Greene * @apiviz.exclude */ public final class Main { static { // Force initialization at the earliest possible point @SuppressWarnings("unused") long start = StartTimeHolder.START_TIME; } private static final String[] NO_STRINGS = new String[0]; private Main() { } private static void usage() { System.out.println("Usage: java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] [args...]"); System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -jar [args...]"); System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -cp [args...]"); System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -class [args...]"); System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar -addindex [-modify] "); System.out.println("where is a valid module specification string"); System.out.println("and options include:"); System.out.println(" -help Display this message"); System.out.println(" -mp, -modulepath "); System.out.println(" A list of directories, separated by '" + File.pathSeparator + "', where modules may be located"); System.out.println(" If not specified, the value of the \"module.path\" system property is used"); System.out.println(" -class Specify that the final argument is a"); System.out.println(" class to load from the class path; not compatible with -jar"); System.out.println(" -cp,-classpath "); System.out.println(" A search path for class files; implies -class"); System.out.println(" -dep,-dependencies [,,...]"); System.out.println(" A list of module dependencies to add to the class path;"); System.out.println(" requires -class or -cp"); System.out.println(" -deptree Print the dependency tree of the given module instead of running it"); System.out.println(" -jar Specify that the final argument is the name of a"); System.out.println(" JAR file to run as a module; not compatible with -class"); System.out.println(" -jaxpmodule "); System.out.println(" The default JAXP implementation to use of the JDK"); System.out.println(" -secmgr Run with a security manager installed; not compatible with -secmgrmodule"); System.out.println(" -secmgrmodule "); System.out.println(" Run with a security manager module; not compatible with -secmgr"); System.out.println(" -addindex Specify that the final argument is a"); System.out.println(" jar to create an index for"); System.out.println(" -modify Modify the indexes jar in-place"); System.out.println(" -version Print version and exit\n"); } /** * Run JBoss Modules. * * @param args the command-line arguments * * @throws Throwable if an error occurs */ public static void main(String[] args) throws Throwable { final int argsLen = args.length; String deps = null; String[] moduleArgs = NO_STRINGS; String modulePath = null; String classpath = null; boolean jar = false; boolean classpathDefined = false; boolean classDefined = false; boolean depTree = false; String nameArgument = null; ModuleIdentifier jaxpModuleIdentifier = null; boolean defaultSecMgr = false; String secMgrModule = null; boolean addIndex = false; boolean modifyInPlace = false; for (int i = 0, argsLength = argsLen; i < argsLength; i++) { final String arg = args[i]; try { if (arg.charAt(0) == '-') { // it's an option if ("-version".equals(arg)) { System.out.println("JBoss Modules version " + getVersionString()); return; } else if ("-help".equals(arg)) { usage(); return; } else if ("-addindex".equals(arg)) { addIndex = true; } else if ("-modify".equals(arg)) { modifyInPlace = true; } else if ("-modulepath".equals(arg) || "-mp".equals(arg)) { if (modulePath != null) { System.err.println("Module path may only be specified once"); System.exit(1); } modulePath = args[++i]; System.setProperty("module.path", modulePath); } else if ("-config".equals(arg)) { System.err.println("Config files are no longer supported. Use the -mp option instead"); System.exit(1); } else if ("-deptree".equals(arg)) { if (depTree) { System.err.println("-deptree may only be specified once"); System.exit(1); } if (jar) { System.err.println("-deptree may not be specified with -jar"); System.exit(1); } if (classDefined) { System.err.println("-deptree may not be specified with -class"); System.exit(1); } if (classpathDefined) { System.err.println("-deptree may not be specified with -classpath"); System.exit(1); } depTree = true; } else if ("-jaxpmodule".equals(arg)) { jaxpModuleIdentifier = ModuleIdentifier.fromString(args[++i]); } else if ("-jar".equals(arg)) { if (jar) { System.err.println("-jar flag may only be specified once"); System.exit(1); } if (classpathDefined) { System.err.println("-cp/-classpath may not be specified with -jar"); System.exit(1); } if (classDefined) { System.err.println("-class may not be specified with -jar"); System.exit(1); } if (depTree) { System.err.println("-deptree may not be specified with -jar"); System.exit(1); } jar = true; } else if ("-cp".equals(arg) || "-classpath".equals(arg)) { if (classpathDefined) { System.err.println("-cp or -classpath may only be specified once."); System.exit(1); } if (classDefined) { System.err.println("-class may not be specified with -cp/classpath"); System.exit(1); } if (jar) { System.err.println("-cp/-classpath may not be specified with -jar"); System.exit(1); } if (depTree) { System.err.println("-deptree may not be specified with -classpath"); System.exit(1); } classpathDefined = true; classpath = args[++i]; doPrivileged(new PropertyWriteAction("java.class.path", classpath)); } else if ("-dep".equals(arg) || "-dependencies".equals(arg)) { if (deps != null) { System.err.println("-dep or -dependencies may only be specified once."); System.exit(1); } deps = args[++i]; } else if ("-class".equals(arg)) { if (classDefined) { System.err.println("-class flag may only be specified once"); System.exit(1); } if (classpathDefined) { System.err.println("-class may not be specified with -cp/classpath"); System.exit(1); } if (jar) { System.err.println("-class may not be specified with -jar"); System.exit(1); } if (depTree) { System.err.println("-deptree may not be specified with -class"); System.exit(1); } classDefined = true; } else if ("-logmodule".equals(arg)) { System.err.println("WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager' or the 'java.util.logging.LogManager' service loader."); i++; } else if ("-secmgr".equals(arg)) { if (defaultSecMgr) { System.err.println("-secmgr may only be specified once"); System.exit(1); } if (secMgrModule != null) { System.err.println("-secmgr may not be specified when -secmgrmodule is given"); System.exit(1); } defaultSecMgr = true; } else if ("-secmgrmodule".equals(arg)) { if (secMgrModule != null) { System.err.println("-secmgrmodule may only be specified once"); System.exit(1); } if (defaultSecMgr) { System.err.println("-secmgrmodule may not be specified when -secmgr is given"); System.exit(1); } secMgrModule = args[++i]; } else { System.err.printf("Invalid option '%s'\n", arg); usage(); System.exit(1); } } else { // it's the module specification nameArgument = arg; int cnt = argsLen - i - 1; moduleArgs = new String[cnt]; System.arraycopy(args, i + 1, moduleArgs, 0, cnt); break; } } catch (IndexOutOfBoundsException e) { System.err.printf("Argument expected for option %s\n", arg); usage(); System.exit(1); } } if (modifyInPlace && ! addIndex) { System.err.println("-modify requires -addindex"); usage(); System.exit(1); } if (addIndex) { if (nameArgument == null) { System.err.println("-addindex requires a target JAR name"); usage(); System.exit(1); } if (modulePath != null) { System.err.println("-mp may not be used with -addindex"); usage(); System.exit(1); } if (jaxpModuleIdentifier != null) { System.err.println("-jaxpModuleIdentifier may not be used with -addindex"); usage(); System.exit(1); } if (classpathDefined) { System.err.println("-cp or -classpath may not be used with -addindex"); usage(); System.exit(1); } if (classDefined) { System.err.println("-class may not be used with -addindex"); usage(); System.exit(1); } if (jar) { System.err.println("-jar may not be used with -addindex"); usage(); System.exit(1); } if (deps != null) { System.err.println("-deps may not be used with -addindex"); usage(); System.exit(1); } if (defaultSecMgr) { System.err.println("-secmgr may not be used with -addindex"); usage(); System.exit(1); } if (secMgrModule != null) { System.err.println("-secmgrmodule may not be used with -addindex"); usage(); System.exit(1); } if (depTree) { System.err.println("-deptree may not be used with -addindex"); usage(); System.exit(1); } JarFileResourceLoader.addInternalIndex(new File(nameArgument), modifyInPlace); return; } if (deps != null && ! classDefined && ! classpathDefined) { System.err.println("-deps may only be specified when -cp/-classpath or -class is in use"); System.exit(1); } // run the module if (nameArgument == null) { if (classDefined || classpathDefined) { System.err.println("No class name specified"); } else if (jar) { System.err.println("No JAR specified"); } else { System.err.println("No module specified"); } usage(); System.exit(1); } if (depTree) { DependencyTreeViewer.print(new PrintWriter(System.out), ModuleIdentifier.fromString(nameArgument), LocalModuleFinder.getRepoRoots(true)); System.exit(0); } final ModuleLoader loader; final ModuleLoader environmentLoader; environmentLoader = DefaultBootModuleLoaderHolder.INSTANCE; final ModuleIdentifier moduleIdentifier; if (jar) { loader = new JarModuleLoader(environmentLoader, new JarFile(nameArgument)); moduleIdentifier = ((JarModuleLoader) loader).getMyIdentifier(); } else if (classpathDefined || classDefined) { loader = new ClassPathModuleLoader(environmentLoader, nameArgument, classpath, deps); moduleIdentifier = ModuleIdentifier.CLASSPATH; } else { loader = environmentLoader; moduleIdentifier = ModuleIdentifier.fromString(nameArgument); } Module.initBootModuleLoader(loader); if (jaxpModuleIdentifier != null) { __JAXPRedirected.changeAll(jaxpModuleIdentifier, Module.getBootModuleLoader()); } else { __JAXPRedirected.changeAll(moduleIdentifier, Module.getBootModuleLoader()); } final Module module; try { module = loader.loadModule(moduleIdentifier); } catch (ModuleNotFoundException e) { e.printStackTrace(System.err); System.exit(1); return; } final String ourJavaVersion = doPrivileged(new PropertyReadAction("java.specification.version", "1.6")); final String requireJavaVersion = module.getProperty("jboss.require-java-version", ourJavaVersion); final Pattern versionPattern = Pattern.compile("1\\.(\\d+)"); final Matcher requireMatcher = versionPattern.matcher(requireJavaVersion); final Matcher ourMatcher = versionPattern.matcher(ourJavaVersion); if (requireMatcher.matches() && ourMatcher.matches() && Integer.valueOf(requireMatcher.group(1)) > Integer.valueOf(ourMatcher.group(1))) { System.err.printf("This application requires Java specification version %s or later to run (this Java virtual machine implements specification version %s)%n", requireJavaVersion, ourJavaVersion); System.exit(1); } ModularURLStreamHandlerFactory.addHandlerModule(module); ModularContentHandlerFactory.addHandlerModule(module); // at this point, having a security manager already installed will prevent correct operation. final SecurityManager existingSecMgr = System.getSecurityManager(); if (existingSecMgr != null) { System.err.println("An existing security manager was detected. You must use the -secmgr switch to start with a security manager."); System.exit(1); return; // not reached } try { final Iterator iterator = module.loadService(Policy.class).iterator(); if (iterator.hasNext()) { Policy.setPolicy(iterator.next()); } } catch (Exception ignored) {} // configure policy so that if SM is enabled, modules can still function final ModulesPolicy policy = new ModulesPolicy(Policy.getPolicy()); Policy.setPolicy(policy); if (secMgrModule != null) { final Module loadedModule; try { loadedModule = loader.loadModule(ModuleIdentifier.fromString(secMgrModule)); } catch (ModuleNotFoundException e) { e.printStackTrace(System.err); System.exit(1); return; } final Iterator iterator = ServiceLoader.load(SecurityManager.class, loadedModule.getClassLoaderPrivate()).iterator(); if (iterator.hasNext()) { System.setSecurityManager(iterator.next()); } else { System.err.println("No security manager found in module " + secMgrModule); System.exit(1); } } if (defaultSecMgr) { final Iterator iterator = module.loadService(SecurityManager.class).iterator(); if (iterator.hasNext()) { System.setSecurityManager(iterator.next()); } else { System.setSecurityManager(new SecurityManager()); } } final ModuleClassLoader bootClassLoader = module.getClassLoaderPrivate(); setContextClassLoader(bootClassLoader); final String serviceName = getServiceName(bootClassLoader, "java.util.prefs.PreferencesFactory"); if (serviceName != null) { final String old = System.setProperty("java.util.prefs.PreferencesFactory", serviceName); try { Preferences.systemRoot(); } finally { if (old == null) { System.clearProperty("java.util.prefs.PreferencesFactory"); } else { System.setProperty("java.util.prefs.PreferencesFactory", old); } } } final String logManagerName = getServiceName(bootClassLoader, "java.util.logging.LogManager"); if (logManagerName != null) { System.setProperty("java.util.logging.manager", logManagerName); if (LogManager.getLogManager().getClass() == LogManager.class) { System.err.println("WARNING: Failed to load the specified log manager class " + logManagerName); } else { Module.setModuleLogger(new JDKModuleLogger()); } } final String mbeanServerBuilderName = getServiceName(bootClassLoader, "javax.management.MBeanServerBuilder"); if (mbeanServerBuilderName != null) { System.setProperty("javax.management.builder.initial", mbeanServerBuilderName); // Initialize the platform mbean server ManagementFactory.getPlatformMBeanServer(); } ModuleLoader.installMBeanServer(); try { module.run(moduleArgs); } catch (InvocationTargetException e) { throw e.getCause(); } return; } private static String getServiceName(ClassLoader classLoader, String className) throws IOException { final InputStream stream = classLoader.getResourceAsStream("META-INF/services/" + className); if (stream == null) { return null; } try { final BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); String line; while ((line = reader.readLine()) != null) { final int i = line.indexOf('#'); if (i != -1) { line = line.substring(0, i); } line = line.trim(); if (line.length() == 0) continue; return line; } return null; } finally { StreamUtil.safeClose(stream); } } private static final String JAR_NAME; private static final String VERSION_STRING; static { final Enumeration resources; String jarName = "(unknown)"; String versionString = "(unknown)"; try { final ClassLoader classLoader = Main.class.getClassLoader(); resources = classLoader == null ? ModuleClassLoader.getSystemResources("META-INF/MANIFEST.MF") : classLoader.getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { final URL url = resources.nextElement(); try { final InputStream stream = url.openStream(); if (stream != null) try { final Manifest manifest = new Manifest(stream); final Attributes mainAttributes = manifest.getMainAttributes(); if (mainAttributes != null && "JBoss Modules".equals(mainAttributes.getValue("Specification-Title"))) { jarName = mainAttributes.getValue("Jar-Name"); versionString = mainAttributes.getValue("Jar-Version"); } } finally { StreamUtil.safeClose(stream); } } catch (IOException ignored) {} } } catch (IOException ignored) {} JAR_NAME = jarName; VERSION_STRING = versionString; } /** * Get the name of the JBoss Modules JAR. * * @return the name */ public static String getJarName() { return JAR_NAME; } /** * Get the version string of JBoss Modules. * * @return the version string */ public static String getVersionString() { return VERSION_STRING; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/MavenArtifactUtil.java000077500000000000000000000337161257205723500276230ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static org.jboss.modules.ModuleXmlParser.endOfDocument; import static org.jboss.modules.ModuleXmlParser.unexpectedContent; import static org.jboss.modules.xml.XmlPullParser.END_DOCUMENT; import static org.jboss.modules.xml.XmlPullParser.END_TAG; import static org.jboss.modules.xml.XmlPullParser.FEATURE_PROCESS_NAMESPACES; import static org.jboss.modules.xml.XmlPullParser.START_TAG; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URLConnection; import java.net.URL; import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.util.List; import org.jboss.modules.xml.MXParser; import org.jboss.modules.xml.XmlPullParser; import org.jboss.modules.xml.XmlPullParserException; /** * Helper class to resolve a maven artifact * * @author Bill Burke * @author Tomaz Cerar * @version $Revision: 2 $ */ class MavenArtifactUtil { private static MavenSettings mavenSettings; private static final Object settingLoaderMutex = new Object(); public static MavenSettings getSettings() throws IOException { if (mavenSettings != null) { return mavenSettings; } synchronized (settingLoaderMutex) { MavenSettings settings = new MavenSettings(); Path m2 = java.nio.file.Paths.get(System.getProperty("user.home"), ".m2"); Path settingsPath = m2.resolve("settings.xml"); if (Files.notExists(settingsPath)) { String mavenHome = System.getenv("M2_HOME"); if (mavenHome != null) { settingsPath = java.nio.file.Paths.get(mavenHome, "conf", "settings.xml"); } } if (Files.exists(settingsPath)) { parseSettingsXml(settingsPath, settings); } if (settings.getLocalRepository() == null) { Path repository = m2.resolve("repository"); settings.setLocalRepository(repository); } settings.resolveActiveSettings(); mavenSettings = settings; return mavenSettings; } } private static MavenSettings parseSettingsXml(Path settings, MavenSettings mavenSettings) throws IOException { try { final MXParser reader = new MXParser(); reader.setFeature(FEATURE_PROCESS_NAMESPACES, false); InputStream source = Files.newInputStream(settings, StandardOpenOption.READ); reader.setInput(source, null); int eventType; while ((eventType = reader.next()) != END_DOCUMENT) { switch (eventType) { case START_TAG: { switch (reader.getName()) { case "settings": { parseSettings(reader, mavenSettings); break; } } } default: { break; } } } return mavenSettings; } catch (XmlPullParserException e) { throw new IOException("Could not parse maven settings.xml"); } } private static void parseSettings(final XmlPullParser reader, MavenSettings mavenSettings) throws XmlPullParserException, IOException { int eventType; while ((eventType = reader.nextTag()) != END_DOCUMENT) { switch (eventType) { case END_TAG: { return; } case START_TAG: { switch (reader.getName()) { case "localRepository": { String localRepository = reader.nextText(); if (!"".equals(localRepository)) { mavenSettings.setLocalRepository(java.nio.file.Paths.get(localRepository)); } break; } case "profiles": { while ((eventType = reader.nextTag()) != END_DOCUMENT) { if (eventType == START_TAG) { switch (reader.getName()) { case "profile": { parseProfile(reader, mavenSettings); break; } } } else { break; } } break; } case "activeProfiles": { while ((eventType = reader.nextTag()) != END_DOCUMENT) { if (eventType == START_TAG) { switch (reader.getName()) { case "activeProfile": { mavenSettings.addActiveProfile(reader.nextText()); break; } } } else { break; } } break; } default: { skip(reader); } } break; } default: { throw unexpectedContent(reader); } } } throw endOfDocument(reader); } private static void parseProfile(final XmlPullParser reader, MavenSettings mavenSettings) throws XmlPullParserException, IOException { int eventType; MavenSettings.Profile profile = new MavenSettings.Profile(); while ((eventType = reader.nextTag()) != END_DOCUMENT) { if (eventType == START_TAG) { switch (reader.getName()) { case "id": { profile.setId(reader.nextText()); break; } case "repositories": { while ((eventType = reader.nextTag()) != END_DOCUMENT) { if (eventType == START_TAG) { switch (reader.getName()) { case "repository": { parseRepository(reader, profile); break; } } } else { break; } } break; } default: { skip(reader); } } } else { break; } } mavenSettings.addProfile(profile); } private static void parseRepository(final XmlPullParser reader, MavenSettings.Profile profile) throws XmlPullParserException, IOException { int eventType; while ((eventType = reader.nextTag()) != END_DOCUMENT) { if (eventType == START_TAG) { switch (reader.getName()) { case "url": { profile.addRepository(reader.nextText()); break; } default: { skip(reader); } } } else { break; } } } private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException { if (parser.getEventType() != XmlPullParser.START_TAG) { throw new IllegalStateException(); } int depth = 1; while (depth != 0) { switch (parser.next()) { case XmlPullParser.END_TAG: depth--; break; case XmlPullParser.START_TAG: depth++; break; } } } private static final Object artifactLock = new Object(); /** * Tries to find a maven jar artifact from the system property "local.maven.repo.path" This property is a list of * platform separated directory names. If not specified, then it looks in ${user.home}/.m2/repository by default. *

* If it can't find it in local paths, then will try to download from a remote repository from the system property * "remote.maven.repo". There is no default remote repository. It will download both the pom and jar and put it * into the first directory listed in "local.maven.repo.path" (or the default dir). This directory will be created * if it doesn't exist. *

* Finally, if you do not want a message to console, then set the system property "maven.download.message" to * "false" * * @param qualifier group:artifact:version[:classifier] * @return absolute path to artifact, null if none exists * @throws IOException */ public static File resolveJarArtifact(String qualifier) throws IOException { String[] split = qualifier.split(":"); if (split.length < 3) { throw new IllegalArgumentException("Illegal artifact " + qualifier); } String groupId = split[0]; String artifactId = split[1]; String version = split[2]; String classifier = ""; if (split.length >= 4) { classifier = "-" + split[3]; } String artifactRelativePath = relativeArtifactPath(groupId, artifactId, version); String artifactRelativeHttpPath = relativeArtifactHttpPath(groupId, artifactId, version); final MavenSettings settings = getSettings(); final Path localRepository = settings.getLocalRepository(); // serialize artifact lookup because we want to prevent parallel download synchronized (artifactLock) { String jarPath = artifactRelativePath + classifier + ".jar"; Path fp = java.nio.file.Paths.get(localRepository.toString(), jarPath); if (Files.exists(fp)) { return fp.toFile(); } List remoteRepos = mavenSettings.getRemoteRepositories(); if (remoteRepos.isEmpty()) { return null; } final File jarFile = new File(localRepository.toFile(), jarPath); final File pomFile = new File(localRepository.toFile(), artifactRelativePath + ".pom"); for (String remoteRepository : remoteRepos) { try { String remotePomPath = remoteRepository + artifactRelativeHttpPath + ".pom"; String remoteJarPath = remoteRepository + artifactRelativeHttpPath + classifier + ".jar"; downloadFile(qualifier + ":pom", remotePomPath, pomFile); downloadFile(qualifier + ":jar", remoteJarPath, jarFile); if (jarFile.exists()) { //download successful return jarFile; } } catch (IOException e) { Module.log.trace(e, "Could not download '%s' from '%s' repository", artifactRelativePath, remoteRepository); // } } //could not find it in remote Module.log.trace("Could not find in any remote repository"); return null; } } public static String relativeArtifactPath(String groupId, String artifactId, String version) { return relativeArtifactPath(File.separatorChar, groupId, artifactId, version); } public static String relativeArtifactHttpPath(String groupId, String artifactId, String version) { return relativeArtifactPath('/', groupId, artifactId, version); } private static String relativeArtifactPath(char separator, String groupId, String artifactId, String version) { StringBuilder builder = new StringBuilder(groupId.replace('.', separator)); builder.append(separator).append(artifactId).append(separator).append(version).append(separator).append(artifactId).append('-').append(version); return builder.toString(); } public static void downloadFile(String artifact, String src, File dest) throws IOException { if (dest.exists()){ return; } final URL url = new URL(src); final URLConnection connection = url.openConnection(); boolean message = Boolean.getBoolean("maven.download.message"); try (InputStream bis = connection.getInputStream()){ dest.getParentFile().mkdirs(); if (message) { System.out.println("Downloading " + artifact); } Files.copy(bis, dest.toPath(), StandardCopyOption.REPLACE_EXISTING); } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/MavenSettings.java000066400000000000000000000054341257205723500270210ustar00rootroot00000000000000package org.jboss.modules; import java.io.File; import java.nio.file.*; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * @author Tomaz Cerar (c) 2014 Red Hat Inc. */ final class MavenSettings { private Path localRepository; private final List remoteRepositories = new LinkedList<>(); private final Map profiles = new HashMap<>(); private final List activeProfileNames = new LinkedList<>(); MavenSettings() { configureDefaults(); } void configureDefaults() { //always add maven central remoteRepositories.add("https://repo1.maven.org/maven2/"); String localRepositoryPath = System.getProperty("local.maven.repo.path"); if (localRepositoryPath != null) { System.out.println("Please use 'maven.repo.local' instead of 'local.maven.repo.path'"); localRepository = java.nio.file.Paths.get(localRepositoryPath.split(File.pathSeparator)[0]); } localRepositoryPath = System.getProperty("maven.repo.local"); if (localRepositoryPath != null) { localRepository = java.nio.file.Paths.get(localRepositoryPath); } String remoteRepository = System.getProperty("remote.maven.repo"); if (remoteRepository != null) { if (!remoteRepository.endsWith("/")) { remoteRepository += "/"; } remoteRepositories.add(remoteRepository); } } public void setLocalRepository(Path localRepository) { this.localRepository = localRepository; } public Path getLocalRepository() { return localRepository; } public List getRemoteRepositories() { return remoteRepositories; } public void addProfile(Profile profile) { this.profiles.put(profile.getId(), profile); } public void addActiveProfile(String profileName) { activeProfileNames.add(profileName); } void resolveActiveSettings() { for (String name : activeProfileNames) { Profile p = profiles.get(name); if (p != null) { remoteRepositories.addAll(p.getRepositories()); } } } static final class Profile { private String id; final List repositories = new LinkedList<>(); Profile() { } public void setId(String id) { this.id = id; } public String getId() { return id; } public void addRepository(String url) { if (!url.endsWith("/")) { url += "/"; } repositories.add(url); } public List getRepositories() { return repositories; } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Metrics.java000066400000000000000000000026021257205723500256320ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.security.AccessController; /** * @author David M. Lloyd */ final class Metrics { static final boolean ENABLED; static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean(); private Metrics() { } static long getCurrentCPUTime() { return ENABLED ? false ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : System.nanoTime() : 0L; } static { ENABLED = Boolean.parseBoolean(AccessController.doPrivileged(new PropertyReadAction("jboss.modules.metrics", "false"))); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModularContentHandlerFactory.java000066400000000000000000000067051257205723500320200ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.net.ContentHandler; import java.net.ContentHandlerFactory; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; import java.util.concurrent.CopyOnWriteArrayList; /** * @author David M. Lloyd */ final class ModularContentHandlerFactory implements ContentHandlerFactory { private static final PrivilegedAction CONTENT_MODULES_LIST_ACTION = new PropertyReadAction("jboss.content.handler.modules"); private static final List modules; static { CopyOnWriteArrayList list = new CopyOnWriteArrayList(); final SecurityManager sm = System.getSecurityManager(); final String urlModulesList; if (sm != null) { urlModulesList = AccessController.doPrivileged(CONTENT_MODULES_LIST_ACTION); } else { urlModulesList = CONTENT_MODULES_LIST_ACTION.run(); } if (urlModulesList != null) { final List moduleList = new ArrayList(); int f = 0; int i; do { i = urlModulesList.indexOf('|', f); final String moduleId = (i == -1 ? urlModulesList.substring(f) : urlModulesList.substring(f, i)).trim(); if (moduleId.length() > 0) { try { final ModuleIdentifier identifier = ModuleIdentifier.fromString(moduleId); Module module = Module.getBootModuleLoader().loadModule(identifier); moduleList.add(module); } catch (RuntimeException e) { // skip it } catch (ModuleLoadException e) { // skip it } } f = i + 1; } while (i != -1); list.addAll(moduleList); } modules = list; } static final ModularContentHandlerFactory INSTANCE = new ModularContentHandlerFactory(); static void addHandlerModule(Module module) { modules.add(module); } public ContentHandler createContentHandler(final String mimeType) { for (Module module : modules) { ServiceLoader loader = module.loadService(ContentHandlerFactory.class); for (ContentHandlerFactory factory : loader) try { final ContentHandler handler = factory.createContentHandler(mimeType); if (handler != null) { return handler; } } catch (RuntimeException e) { // ignored } } return null; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModularURLStreamHandlerFactory.java000066400000000000000000000110161257205723500322130ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; /** * The root URL stream handler factory for the module system. * * @author David M. Lloyd */ final class ModularURLStreamHandlerFactory implements URLStreamHandlerFactory { private static final PrivilegedAction URL_MODULES_LIST_ACTION = new PropertyReadAction("jboss.protocol.handler.modules"); private static final List modules; private static final ThreadLocal> reentered = new ThreadLocal>() { protected Set initialValue() { return new FastCopyHashSet(); } }; static { CopyOnWriteArrayList list = new CopyOnWriteArrayList(); final SecurityManager sm = System.getSecurityManager(); final String urlModulesList; if (sm != null) { urlModulesList = AccessController.doPrivileged(URL_MODULES_LIST_ACTION); } else { urlModulesList = URL_MODULES_LIST_ACTION.run(); } if (urlModulesList != null) { final List moduleList = new ArrayList(); int f = 0; int i; do { i = urlModulesList.indexOf('|', f); final String moduleId = (i == -1 ? urlModulesList.substring(f) : urlModulesList.substring(f, i)).trim(); if (moduleId.length() > 0) { try { final ModuleIdentifier identifier = ModuleIdentifier.fromString(moduleId); Module module = Module.getBootModuleLoader().loadModule(identifier); moduleList.add(module); } catch (RuntimeException e) { // skip it } catch (ModuleLoadException e) { // skip it } } f = i + 1; } while (i != -1); list.addAll(moduleList); } modules = list; } static final ModularURLStreamHandlerFactory INSTANCE = new ModularURLStreamHandlerFactory(); static void addHandlerModule(Module module) { modules.add(module); } private ModularURLStreamHandlerFactory() { } private URLStreamHandler locateHandler(final String protocol) { for (Module module : modules) { ServiceLoader loader = module.loadService(URLStreamHandlerFactory.class); for (URLStreamHandlerFactory factory : loader) { try { final URLStreamHandler handler = factory.createURLStreamHandler(protocol); if (handler != null) { return handler; } } catch (RuntimeException e) { // ignored } } } return null; } public URLStreamHandler createURLStreamHandler(final String protocol) { final Set set = reentered.get(); if (set.add(protocol)) { try { if (System.getSecurityManager() == null) { return locateHandler(protocol); } return AccessController.doPrivileged(new PrivilegedAction() { public URLStreamHandler run() { return locateHandler(protocol); } }); } finally { set.remove(protocol); } } return null; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Module.java000066400000000000000000001765161257205723500254710ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLConnection; import java.security.AccessController; import java.security.PermissionCollection; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import org.jboss.modules._private.ModulesPrivateAccess; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.ClassFilters; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.log.ModuleLogger; import org.jboss.modules.log.NoopModuleLogger; import __redirected.__JAXPRedirected; import org.jboss.modules.security.ModularPermissionFactory; /** * A module is a unit of classes and other resources, along with the specification of what is imported and exported * by this module from and to other modules. Modules are created by {@link ModuleLoader}s which build modules from * various configuration information and resource roots. * * @author David M. Lloyd * @author John Bailey * @author Flavia Rainone * @author Jason T. Greene * @author thomas.diesler@jboss.com * * @apiviz.landmark */ public final class Module { private static final AtomicReference BOOT_MODULE_LOADER; static { log = NoopModuleLogger.getInstance(); BOOT_MODULE_LOADER = new AtomicReference(); EMPTY_CLASS_FILTERS = new FastCopyHashSet(0); EMPTY_PATH_FILTERS = new FastCopyHashSet(0); GET_DEPENDENCIES = new RuntimePermission("getDependencies"); GET_CLASS_LOADER = new RuntimePermission("getClassLoader"); GET_BOOT_MODULE_LOADER = new RuntimePermission("getBootModuleLoader"); ACCESS_MODULE_LOGGER = new RuntimePermission("accessModuleLogger"); ADD_CONTENT_HANDLER_FACTORY = new RuntimePermission("addContentHandlerFactory"); ADD_URL_STREAM_HANDLER_FACTORY = new RuntimePermission("addURLStreamHandlerFactory"); final String pkgsString = AccessController.doPrivileged(new PropertyReadAction("jboss.modules.system.pkgs")); final List list = new ArrayList(); list.add("java."); list.add("sun.reflect."); list.add("__redirected."); if (pkgsString != null) { int i; int nc = -1; do { i = nc + 1; nc = pkgsString.indexOf(',', i); String part; if (nc == -1) { part = pkgsString.substring(i).trim(); } else { part = pkgsString.substring(i, nc).trim(); } if (part.length() > 0) { list.add((part + ".").intern()); } } while (nc != -1); } systemPackages = list.toArray(list.toArray(new String[list.size()])); final ListIterator iterator = list.listIterator(); // http://youtrack.jetbrains.net/issue/IDEA-72097 //noinspection WhileLoopReplaceableByForEach while (iterator.hasNext()) { iterator.set(iterator.next().replace('.', '/')); } systemPaths = list.toArray(list.toArray(new String[list.size()])); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { try { URL.setURLStreamHandlerFactory(ModularURLStreamHandlerFactory.INSTANCE); } catch (Throwable t) { // todo log a warning or something } try { URLConnection.setContentHandlerFactory(ModularContentHandlerFactory.INSTANCE); } catch (Throwable t) { // todo log a warning or something } __JAXPRedirected.initAll(); return null; } }); } // static properties static final String[] systemPackages; static final String[] systemPaths; static final ModulesPrivateAccess PRIVATE_ACCESS = new ModulesPrivateAccess() { public ModuleClassLoader getClassLoaderOf(final Module module) { return module.getClassLoaderPrivate(); } }; /** * Private access for module internal code. Throws {@link SecurityException} for user code. * * @throws SecurityException always */ public static ModulesPrivateAccess getPrivateAccess() { if (CallerContext.getCallingClass() == ModularPermissionFactory.class) { return PRIVATE_ACCESS; } throw new SecurityException(); } /** * The system-wide module logger, which may be changed via {@link #setModuleLogger(org.jboss.modules.log.ModuleLogger)}. */ static volatile ModuleLogger log; private static final FastCopyHashSet EMPTY_CLASS_FILTERS; private static final FastCopyHashSet EMPTY_PATH_FILTERS; // immutable properties /** * The identifier of this module. */ private final ModuleIdentifier identifier; /** * The name of the main class, if any (may be {@code null}). */ private final String mainClassName; /** * The module class loader for this module. */ private final ModuleClassLoader moduleClassLoader; /** * The module loader which created this module. */ private final ModuleLoader moduleLoader; /** * The fallback local loader, if any is defined. */ private final LocalLoader fallbackLoader; /** * The properties map specified when this module was defined. */ private final Map properties; /** * The assigned permission collection. */ private final PermissionCollection permissionCollection; // mutable properties /** * The linkage state. */ private volatile Linkage linkage = Linkage.NONE; // private constants private static final RuntimePermission GET_DEPENDENCIES; private static final RuntimePermission GET_CLASS_LOADER; private static final RuntimePermission GET_BOOT_MODULE_LOADER; private static final RuntimePermission ACCESS_MODULE_LOGGER; private static final RuntimePermission ADD_CONTENT_HANDLER_FACTORY; private static final RuntimePermission ADD_URL_STREAM_HANDLER_FACTORY; /** * Construct a new instance from a module specification. * * @param spec the module specification * @param moduleLoader the module loader */ Module(final ConcreteModuleSpec spec, final ModuleLoader moduleLoader) { this.moduleLoader = moduleLoader; // Initialize state from the spec. identifier = spec.getModuleIdentifier(); mainClassName = spec.getMainClass(); fallbackLoader = spec.getFallbackLoader(); permissionCollection = spec.getPermissionCollection(); //noinspection ThisEscapedInObjectConstruction final ModuleClassLoader.Configuration configuration = new ModuleClassLoader.Configuration(this, spec.getAssertionSetting(), spec.getResourceLoaders(), spec.getClassFileTransformer()); final ModuleClassLoaderFactory factory = spec.getModuleClassLoaderFactory(); ModuleClassLoader moduleClassLoader = null; if (factory != null) moduleClassLoader = factory.create(configuration); if (moduleClassLoader == null) moduleClassLoader = new ModuleClassLoader(configuration); this.moduleClassLoader = moduleClassLoader; final Map properties = spec.getProperties(); this.properties = properties.isEmpty() ? Collections.emptyMap() : new LinkedHashMap(properties); } LocalLoader getFallbackLoader() { return fallbackLoader; } Dependency[] getDependenciesInternal() { return linkage.getDependencies(); } DependencySpec[] getDependencySpecsInternal() { return linkage.getDependencySpecs(); } ModuleClassLoader getClassLoaderPrivate() { return moduleClassLoader; } /** * Get the current dependencies of this module. * * @return the current dependencies of this module * @throws SecurityException if a security manager is enabled and the caller does not have the {@code getDependencies} * {@link RuntimePermission} */ public DependencySpec[] getDependencies() throws SecurityException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(GET_DEPENDENCIES); } return getDependencySpecsInternal().clone(); } /** * Get an exported resource from a specific root in this module. * * @param rootPath the module root to search * @param resourcePath the path of the resource * @return the resource */ public Resource getExportedResource(final String rootPath, final String resourcePath) { return moduleClassLoader.loadResourceLocal(rootPath, resourcePath); } /** * Run a module's main class, if any. * * @param args the arguments to pass * @throws NoSuchMethodException if there is no main method * @throws InvocationTargetException if the main method failed * @throws ClassNotFoundException if the main class is not found */ public void run(final String[] args) throws NoSuchMethodException, InvocationTargetException, ClassNotFoundException { try { if (mainClassName == null) { throw new NoSuchMethodException("No main class defined for " + this); } final ClassLoader oldClassLoader = SecurityActions.setContextClassLoader(moduleClassLoader); try { final Class mainClass = Class.forName(mainClassName, false, moduleClassLoader); try { Class.forName(mainClassName, true, moduleClassLoader); } catch (Throwable t) { throw new InvocationTargetException(t, "Failed to initialize main class '" + mainClassName + "'"); } final Method mainMethod = mainClass.getMethod("main", String[].class); final int modifiers = mainMethod.getModifiers(); if (! Modifier.isStatic(modifiers)) { throw new NoSuchMethodException("Main method is not static for " + this); } // ignore the return value mainMethod.invoke(null, new Object[] {args}); } finally { SecurityActions.setContextClassLoader(oldClassLoader); } } catch (IllegalAccessException e) { // unexpected; should be public throw new IllegalAccessError(e.getMessage()); } } /** * Get this module's identifier. * * @return the identifier */ public ModuleIdentifier getIdentifier() { return identifier; } /** * Get the module loader which created this module. * * @return the module loader of this module */ public ModuleLoader getModuleLoader() { return moduleLoader; } /** * Load a service loader from this module. * * @param serviceType the service type class * @param the service type * @return the service loader */ public ServiceLoader loadService(Class serviceType) { return ServiceLoader.load(serviceType, moduleClassLoader); } /** * Load a service loader from a module in the caller's module loader. The caller's * module loader refers to the loader of the module of the class that calls this method. * Note that {@link #loadService(Class)} is more efficient since it does not need to crawl * the stack. * * @param the the service type * @param identifier the module identifier containing the service loader * @param serviceType the service type class * @return the loaded service from the caller's module * @throws ModuleLoadException if the named module failed to load */ public static ServiceLoader loadServiceFromCallerModuleLoader(ModuleIdentifier identifier, Class serviceType) throws ModuleLoadException { return getCallerModuleLoader().loadModule(identifier).loadService(serviceType); } /** * Get the class loader for a module. The class loader can be used to access non-exported classes and * resources of the module. *

* If a security manager is present, then this method invokes the security manager's {@code checkPermission} method * with a RuntimePermission("getClassLoader") permission to verify access to the class loader. If * access is not granted, a {@code SecurityException} will be thrown. * * @return the module class loader */ public ModuleClassLoader getClassLoader() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(GET_CLASS_LOADER); } return moduleClassLoader; } /** * Get all the paths exported by this module. * * @return the paths that are exported by this module */ public Set getExportedPaths() { return Collections.unmodifiableSet(getPathsUnchecked().keySet()); } /** * Get the module for a loaded class, or {@code null} if the class did not come from any module. * * @param clazz the class * @return the module it came from */ public static Module forClass(Class clazz) { final ClassLoader cl = clazz.getClassLoader(); return forClassLoader(cl, false); } /** * Get the module for a class loader, or {@code null} if the class loader is not associated with any module. If * the class loader is unknown, it is possible to check the parent class loader up the chain, and so on until a module is found. * * @param cl the class loader * @param search {@code true} to search up the delegation chain * @return the associated module */ public static Module forClassLoader(ClassLoader cl, boolean search) { if (cl instanceof ModuleClassLoader) { return ((ModuleClassLoader) cl).getModule(); } else if (search && cl != null) { return forClassLoader(cl.getParent(), true); } else { return null; } } /** * Gets the boot module loader. The boot module loader is the * initial loader that is established by the module framework. It typically * is based off of the environmental module path unless it is overridden by * specifying a different class name for the {@code boot.module.loader} system * property. * * @return the boot module loader */ public static ModuleLoader getBootModuleLoader() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(GET_BOOT_MODULE_LOADER); } ModuleLoader loader; while ((loader = BOOT_MODULE_LOADER.get()) == null) { loader = DefaultBootModuleLoaderHolder.INSTANCE; if (BOOT_MODULE_LOADER.compareAndSet(null, loader)) { break; } // get it again } return loader; } static void initBootModuleLoader(ModuleLoader loader) { BOOT_MODULE_LOADER.set(loader); } /** * Gets the current module loader. The current module loader is the * loader of the module from the calling class. Note that this method * must crawl the stack to determine this, so other mechanisms are more * efficient. * * @return the current module loader, or {@code null} if this method is called outside of a module */ public static ModuleLoader getCallerModuleLoader() { Module callerModule = getCallerModule(); return callerModule == null ? null : callerModule.getModuleLoader(); } /** * Get the current thread's context module loader. This loader is the one which defined the module * whose class loader is, or is a parent of, the thread's current context class loader. If there is none, * then {@code null} is returned. * * @return the module loader, or {@code null} if none is set */ public static ModuleLoader getContextModuleLoader() { return Module.forClassLoader(Thread.currentThread().getContextClassLoader(), true).getModuleLoader(); } /** * Get a module from the current module loader. Note that this must crawl the * stack to determine this, so other mechanisms are more efficient. * @see #getCallerModuleLoader() * * @param identifier the module identifier * @return the module * @throws ModuleLoadException if the module could not be loaded */ public static Module getModuleFromCallerModuleLoader(final ModuleIdentifier identifier) throws ModuleLoadException { return getCallerModuleLoader().loadModule(identifier); } /** * Get the caller's module. The caller's module is the module containing the method that calls this * method. Note that this method crawls the stack so other ways of obtaining the * module are more efficient. * * @return the current module */ public static Module getCallerModule() { return forClass(CallerContext.getCallingClass()); } /** * Get the module with the given identifier from the module loader used by this module. * * @param identifier the module identifier * @return the module * @throws ModuleLoadException if an error occurs */ public Module getModule(final ModuleIdentifier identifier) throws ModuleLoadException { return moduleLoader.loadModule(identifier); } /** * Load a class from a module in the system module loader. * * @see #getBootModuleLoader() * * @param moduleIdentifier the identifier of the module from which the class * should be loaded * @param className the class name to load * @return the class * @throws ModuleLoadException if the module could not be loaded * @throws ClassNotFoundException if the class could not be loaded */ public static Class loadClassFromBootModuleLoader(final ModuleIdentifier moduleIdentifier, final String className) throws ModuleLoadException, ClassNotFoundException { return Class.forName(className, true, getBootModuleLoader().loadModule(moduleIdentifier).getClassLoader()); } /** * Load a class from a module in the caller's module loader. * * @see #getCallerModuleLoader() * * @param moduleIdentifier the identifier of the module from which the class * should be loaded * @param className the class name to load * @return the class * @throws ModuleLoadException if the module could not be loaded * @throws ClassNotFoundException if the class could not be loaded */ public static Class loadClassFromCallerModuleLoader(final ModuleIdentifier moduleIdentifier, final String className) throws ModuleLoadException, ClassNotFoundException { return Class.forName(className, true, getModuleFromCallerModuleLoader(moduleIdentifier).getClassLoader()); } /** * Load a class from a local loader. * * @param className the class name * @param resolve {@code true} to resolve the class after definition * @return the class */ Class loadModuleClass(final String className, final boolean resolve) throws ClassNotFoundException { for (String s : systemPackages) { if (className.startsWith(s)) { return moduleClassLoader.loadClass(className, resolve); } } final String path = pathOfClass(className); final Map> paths = getPathsUnchecked(); final List loaders = paths.get(path); if (loaders != null) { Class clazz; for (LocalLoader loader : loaders) { clazz = loader.loadClassLocal(className, resolve); if (clazz != null) { return clazz; } } } final LocalLoader fallbackLoader = this.fallbackLoader; if (fallbackLoader != null) { return fallbackLoader.loadClassLocal(className, resolve); } return null; } /** * Load a resource from a local loader. * * @param name the resource name * @return the resource URL, or {@code null} if not found */ URL getResource(final String name) { final String canonPath = PathUtils.canonicalize(name); for (String s : Module.systemPaths) { if (canonPath.startsWith(s)) { return moduleClassLoader.getResource(canonPath); } } log.trace("Attempting to find resource %s in %s", canonPath, this); final String path = pathOf(canonPath); final Map> paths = getPathsUnchecked(); final List loaders = paths.get(path); if (loaders != null) { for (LocalLoader loader : loaders) { final List resourceList = loader.loadResourceLocal(canonPath); for (Resource resource : resourceList) { return resource.getURL(); } } } final LocalLoader fallbackLoader = this.fallbackLoader; if (fallbackLoader != null) { final List resourceList = fallbackLoader.loadResourceLocal(canonPath); for (Resource resource : resourceList) { return resource.getURL(); } } return null; } /** * Load a resource from a local loader. * * @param name the resource name * @return the resource stream, or {@code null} if not found */ InputStream getResourceAsStream(final String name) throws IOException { final String canonPath = PathUtils.canonicalize(name); for (String s : Module.systemPaths) { if (canonPath.startsWith(s)) { return moduleClassLoader.getResourceAsStream(canonPath); } } log.trace("Attempting to find resource %s in %s", canonPath, this); final String path = pathOf(canonPath); final Map> paths = getPathsUnchecked(); final List loaders = paths.get(path); if (loaders != null) { for (LocalLoader loader : loaders) { final List resourceList = loader.loadResourceLocal(canonPath); for (Resource resource : resourceList) { return resource.openStream(); } } } final LocalLoader fallbackLoader = this.fallbackLoader; if (fallbackLoader != null) { final List resourceList = fallbackLoader.loadResourceLocal(canonPath); for (Resource resource : resourceList) { return resource.openStream(); } } return null; } /** * Load all resources of a given name from a local loader. * * @param name the resource name * @return the enumeration of all the matching resource URLs (may be empty) */ Enumeration getResources(final String name) { final String canonPath = PathUtils.canonicalize(PathUtils.relativize(name)); for (String s : Module.systemPaths) { if (canonPath.startsWith(s)) { try { return moduleClassLoader.getResources(canonPath); } catch (IOException e) { return ConcurrentClassLoader.EMPTY_ENUMERATION; } } } log.trace("Attempting to find all resources %s in %s", canonPath, this); final String path = pathOf(canonPath); final Map> paths = getPathsUnchecked(); final List loaders = paths.get(path); final List list = new ArrayList(); if (loaders != null) { for (LocalLoader loader : loaders) { final List resourceList = loader.loadResourceLocal(canonPath); for (Resource resource : resourceList) { list.add(resource.getURL()); } } } final LocalLoader fallbackLoader = this.fallbackLoader; if (fallbackLoader != null) { final List resourceList = fallbackLoader.loadResourceLocal(canonPath); for (Resource resource : resourceList) { list.add(resource.getURL()); } } return list.size() == 0 ? ConcurrentClassLoader.EMPTY_ENUMERATION : Collections.enumeration(list); } /** * Get an exported resource URL. * * @param name the resource name * @return the resource, or {@code null} if it was not found */ public URL getExportedResource(final String name) { return getResource(name); } /** * Get all exported resource URLs for a resource name. * * @param name the resource name * @return the resource URLs */ public Enumeration getExportedResources(final String name) { return getResources(name); } /** * Enumerate all the imported resources in this module, subject to a path filter. The filter applies to * the containing path of each resource. * * @param filter the filter to apply to the search * @return the resource iterator (possibly empty) * @throws ModuleLoadException if linking a dependency module fails for some reason */ public Iterator iterateResources(final PathFilter filter) throws ModuleLoadException { final Map> paths = getPaths(); final Iterator>> iterator = paths.entrySet().iterator(); return new Iterator() { private String path; private Iterator resourceIterator; private Iterator loaderIterator; private Resource next; public boolean hasNext() { while (next == null) { if (resourceIterator != null) { assert path != null; if (resourceIterator.hasNext()) { next = resourceIterator.next(); return true; } resourceIterator = null; } if (loaderIterator != null) { assert path != null; if (loaderIterator.hasNext()) { final LocalLoader loader = loaderIterator.next(); if (loader instanceof IterableLocalLoader) { resourceIterator = ((IterableLocalLoader)loader).iterateResources(path, false); continue; } } loaderIterator = null; } if (! iterator.hasNext()) { return false; } final Map.Entry> entry = iterator.next(); path = entry.getKey(); if (filter.accept(path)) { loaderIterator = entry.getValue().iterator(); } } return true; } public Resource next() { if (! hasNext()) throw new NoSuchElementException(); try { return next; } finally { next = null; } } public void remove() { throw new UnsupportedOperationException(); } }; } /** * Enumerate all imported resources in this module which match the given glob expression. The glob applies to * the whole resource name. * * @param glob the glob to apply * @return the iterator * @throws ModuleLoadException if linking a dependency module fails for some reason */ public Iterator globResources(final String glob) throws ModuleLoadException { String safeGlob = PathUtils.canonicalize(PathUtils.relativize(glob)); final int i = safeGlob.lastIndexOf('/'); if (i == -1) { return PathFilters.filtered(PathFilters.match(glob), iterateResources(PathFilters.acceptAll())); } else { return PathFilters.filtered(PathFilters.match(glob.substring(i + 1)), iterateResources(PathFilters.match(glob.substring(0, i)))); } } /** * Get the (unmodifiable) set of paths which are imported into this module class loader, including local paths. The * set will include all paths defined by the module's resource loaders, minus any paths excluded by filters. The * set will generally always contain an empty entry (""). The set is unordered and unsorted, and is iterable in * O(n) time and accessible in O(1) time. * * @return the set of paths * @throws ModuleLoadException if the module was previously unlinked, and there was an exception while linking */ public final Set getImportedPaths() throws ModuleLoadException { return Collections.unmodifiableSet(getPaths().keySet()); } /** * Get the path name of a class. * * @param className the binary name of the class * @return the parent path */ static String pathOfClass(final String className) { final String resourceName = className.replace('.', '/'); final String path; final int idx = resourceName.lastIndexOf('/'); if (idx > -1) { path = resourceName.substring(0, idx); } else { path = ""; } return path; } /** * Get the path name of a resource. * * @param resourceName the resource name * @return the parent path */ static String pathOf(final String resourceName) { final String path; if (resourceName.indexOf('/') == 0) { return pathOf(resourceName.substring(1)); } final int idx = resourceName.lastIndexOf('/'); if (idx > -1) { path = resourceName.substring(0, idx); } else { path = ""; } return path; } /** * Get the file name of a class. * * @param className the class name * @return the name of the corresponding class file */ static String fileNameOfClass(final String className) { return className.replace('.', '/') + ".class"; } /** * Get the property with the given name, or {@code null} if none was defined. * * @param name the property name * @return the property value */ public String getProperty(String name) { return properties.get(name); } /** * Get the property with the given name, or a default value if none was defined. * * @param name the property name * @param defaultVal the default value * @return the property value */ public String getProperty(String name, String defaultVal) { return properties.containsKey(name) ? properties.get(name) : defaultVal; } /** * Get a copy of the list of property names. * * @return the property names list */ public List getPropertyNames() { return new ArrayList(properties.keySet()); } /** * Get the string representation of this module. * * @return the string representation */ @Override public String toString() { return "Module \"" + identifier + "\"" + " from " + moduleLoader.toString(); } /** * Get the logger used by the module system. *

* If a security manager is present, then this method invokes the security manager's {@code checkPermission} method * with a RuntimePermission("accessModuleLogger") permission to verify access to the module logger. If * access is not granted, a {@code SecurityException} will be thrown. * * @return the module logger */ public static ModuleLogger getModuleLogger() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(ACCESS_MODULE_LOGGER); } return log; } /** * Change the logger used by the module system. *

* If a security manager is present, then this method invokes the security manager's {@code checkPermission} method * with a RuntimePermission("accessModuleLogger") permission to verify access to the module logger. If * access is not granted, a {@code SecurityException} will be thrown. * * @param logger the new logger, must not be {@code null} */ public static void setModuleLogger(final ModuleLogger logger) { if (logger == null) { throw new IllegalArgumentException("logger is null"); } final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(ACCESS_MODULE_LOGGER); } logger.greeting(); log = logger; } /** * Return the start time in millis when Module.class was loaded. * * @return start time of Module.class load */ public static long getStartTime() { return StartTimeHolder.START_TIME; } /** * Register an additional module which contains content handlers. *

* If a security manager is present, then this method invokes the security manager's {@code checkPermission} method * with a RuntimePermission("addContentHandlerFactory") permission to verify access. If * access is not granted, a {@code SecurityException} will be thrown. * * @param module the module to add */ public static void registerContentHandlerFactoryModule(Module module) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(ADD_CONTENT_HANDLER_FACTORY); } ModularContentHandlerFactory.addHandlerModule(module); } /** * Register an additional module which contains URL handlers. *

* If a security manager is present, then this method invokes the security manager's {@code checkPermission} method * with a RuntimePermission("addURLStreamHandlerFactory") permission to verify access. If * access is not granted, a {@code SecurityException} will be thrown. * * @param module the module to add */ public static void registerURLStreamHandlerFactoryModule(Module module) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(ADD_URL_STREAM_HANDLER_FACTORY); } ModularURLStreamHandlerFactory.addHandlerModule(module); } /** * Get the platform identifier. This is the string that uniquely identifies the hardware and OS combination for * the current running system. * * @return the platform identifier */ public static String getPlatformIdentifier() { return NativeLibraryResourceLoader.getArchName(); } PermissionCollection getPermissionCollection() { return permissionCollection; } // Linking and resolution static final class Visited { private final Module module; private final FastCopyHashSet filters; private final FastCopyHashSet classFilters; private final FastCopyHashSet resourceFilters; private final int hashCode; Visited(final Module module, final FastCopyHashSet filters, final FastCopyHashSet classFilters, final FastCopyHashSet resourceFilters) { this.module = module; this.filters = filters; this.classFilters = classFilters; this.resourceFilters = resourceFilters; hashCode = ((resourceFilters.hashCode() * 13 + classFilters.hashCode()) * 13 + filters.hashCode()) * 13 + module.hashCode(); } public int hashCode() { return hashCode; } public boolean equals(Object other) { return other instanceof Visited && equals((Visited)other); } public boolean equals(Visited other) { return this == other || other != null && module == other.module && filters.equals(other.filters) && classFilters.equals(other.classFilters) && resourceFilters.equals(other.resourceFilters); } } private long addPaths(Dependency[] dependencies, Map> map, FastCopyHashSet filterStack, FastCopyHashSet classFilterStack, final FastCopyHashSet resourceFilterStack, Set visited) throws ModuleLoadException { long subtract = 0L; moduleLoader.incScanCount(); for (Dependency dependency : dependencies) { if (dependency instanceof ModuleDependency) { final ModuleDependency moduleDependency = (ModuleDependency) dependency; final ModuleLoader moduleLoader = moduleDependency.getModuleLoader(); final ModuleIdentifier id = moduleDependency.getIdentifier(); final Module module; try { long pauseStart = Metrics.getCurrentCPUTime(); try { module = moduleLoader.preloadModule(id); } finally { subtract += Metrics.getCurrentCPUTime() - pauseStart; } } catch (ModuleLoadException ex) { if (moduleDependency.isOptional()) { continue; } else { log.trace("Module %s, dependency %s preload failed: %s", getIdentifier(), moduleDependency.getIdentifier(), ex); throw ex; } } if (module == null) { if (!moduleDependency.isOptional()) { throw new ModuleNotFoundException(id.toString()); } continue; } final PathFilter importFilter = dependency.getImportFilter(); final FastCopyHashSet nestedFilters; final FastCopyHashSet nestedClassFilters; final FastCopyHashSet nestedResourceFilters; if (filterStack.contains(importFilter)) { nestedFilters = filterStack; } else { nestedFilters = filterStack.clone(); nestedFilters.add(importFilter); } final ClassFilter classImportFilter = dependency.getClassImportFilter(); if (classImportFilter == ClassFilters.acceptAll() || classFilterStack.contains(classImportFilter)) { nestedClassFilters = classFilterStack; } else { nestedClassFilters = classFilterStack.clone(); if (classImportFilter != ClassFilters.acceptAll()) nestedClassFilters.add(classImportFilter); } final PathFilter resourceImportFilter = dependency.getResourceImportFilter(); if (resourceImportFilter == PathFilters.acceptAll() || resourceFilterStack.contains(resourceImportFilter)) { nestedResourceFilters = resourceFilterStack; } else { nestedResourceFilters = resourceFilterStack.clone(); if (resourceImportFilter != PathFilters.acceptAll()) nestedResourceFilters.add(resourceImportFilter); } subtract += module.addExportedPaths(module.getDependenciesInternal(), map, nestedFilters, nestedClassFilters, nestedResourceFilters, visited); } else if (dependency instanceof ModuleClassLoaderDependency) { final ModuleClassLoaderDependency classLoaderDependency = (ModuleClassLoaderDependency) dependency; LocalLoader localLoader = classLoaderDependency.getLocalLoader(); for (Object filter : classFilterStack.getRawArray()) { if (filter != null && filter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader((ClassFilter) filter, localLoader); } } for (Object filter : resourceFilterStack.getRawArray()) { if (filter != null && filter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader((PathFilter) filter, localLoader); } } ClassFilter classFilter = classLoaderDependency.getClassImportFilter(); if (classFilter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader(classFilter, localLoader); } PathFilter resourceFilter = classLoaderDependency.getResourceImportFilter(); if (resourceFilter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader(resourceFilter, localLoader); } final PathFilter importFilter = classLoaderDependency.getImportFilter(); final Set paths = classLoaderDependency.getPaths(); for (String path : paths) { if (importFilter.accept(path)) { List list = map.get(path); if (list == null) { map.put(path, list = new ArrayList()); list.add(localLoader); } else if (! list.contains(localLoader)) { list.add(localLoader); } } } } else if (dependency instanceof LocalDependency) { final LocalDependency localDependency = (LocalDependency) dependency; LocalLoader localLoader = localDependency.getLocalLoader(); for (Object filter : classFilterStack.getRawArray()) { if (filter != null && filter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader((ClassFilter) filter, localLoader); } } for (Object filter : resourceFilterStack.getRawArray()) { if (filter != null && filter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader((PathFilter) filter, localLoader); } } final ClassFilter classFilter = localDependency.getClassImportFilter(); if (classFilter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader(classFilter, localLoader); } final PathFilter resourceFilter = localDependency.getResourceImportFilter(); if (resourceFilter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader(resourceFilter, localLoader); } final PathFilter importFilter = localDependency.getImportFilter(); final Set paths = localDependency.getPaths(); for (String path : paths) { if (importFilter.accept(path)) { List list = map.get(path); if (list == null) { map.put(path, list = new ArrayList()); list.add(localLoader); } else if (! list.contains(localLoader)) { list.add(localLoader); } } } } // else unknown dep type so just skip } return subtract; } private LocalLoader createPathFilteredLocalLoader(PathFilter filter, LocalLoader localLoader) { if (localLoader instanceof IterableLocalLoader) return LocalLoaders.createIterablePathFilteredLocalLoader(filter, (IterableLocalLoader) localLoader); else return LocalLoaders.createPathFilteredLocalLoader(filter, localLoader); } private LocalLoader createClassFilteredLocalLoader(ClassFilter filter, LocalLoader localLoader) { if (localLoader instanceof IterableLocalLoader) return LocalLoaders.createIterableClassFilteredLocalLoader(filter, (IterableLocalLoader) localLoader); else return LocalLoaders.createClassFilteredLocalLoader(filter, localLoader); } private long addExportedPaths(Dependency[] dependencies, Map> map, FastCopyHashSet filterStack, FastCopyHashSet classFilterStack, final FastCopyHashSet resourceFilterStack, Set visited) throws ModuleLoadException { if (!visited.add(new Visited(this, filterStack, classFilterStack, resourceFilterStack))) { return 0L; } long subtract = 0L; moduleLoader.incScanCount(); for (Dependency dependency : dependencies) { final PathFilter exportFilter = dependency.getExportFilter(); // skip non-exported dependencies altogether if (exportFilter != PathFilters.rejectAll()) { if (dependency instanceof ModuleDependency) { final ModuleDependency moduleDependency = (ModuleDependency) dependency; final ModuleLoader moduleLoader = moduleDependency.getModuleLoader(); final ModuleIdentifier id = moduleDependency.getIdentifier(); final Module module; try { long pauseStart = Metrics.getCurrentCPUTime(); try { module = moduleLoader.preloadModule(id); } finally { subtract += Metrics.getCurrentCPUTime() - pauseStart; } } catch (ModuleLoadException ex) { if (moduleDependency.isOptional()) { continue; } else { log.trace("Module %s, dependency %s preload failed: %s", getIdentifier(), moduleDependency.getIdentifier(), ex); throw ex; } } if (module == null) { if (!moduleDependency.isOptional()) { throw new ModuleNotFoundException(id.toString()); } continue; } final PathFilter importFilter = dependency.getImportFilter(); final FastCopyHashSet nestedFilters; final FastCopyHashSet nestedClassFilters; final FastCopyHashSet nestedResourceFilters; if (filterStack.contains(importFilter) && filterStack.contains(exportFilter)) { nestedFilters = filterStack; } else { nestedFilters = filterStack.clone(); nestedFilters.add(importFilter); nestedFilters.add(exportFilter); } final ClassFilter classImportFilter = dependency.getClassImportFilter(); final ClassFilter classExportFilter = dependency.getClassExportFilter(); if ((classImportFilter == ClassFilters.acceptAll() || classFilterStack.contains(classImportFilter)) && (classExportFilter == ClassFilters.acceptAll() || classFilterStack.contains(classExportFilter))) { nestedClassFilters = classFilterStack; } else { nestedClassFilters = classFilterStack.clone(); if (classImportFilter != ClassFilters.acceptAll()) nestedClassFilters.add(classImportFilter); if (classExportFilter != ClassFilters.acceptAll()) nestedClassFilters.add(classExportFilter); } final PathFilter resourceImportFilter = dependency.getResourceImportFilter(); final PathFilter resourceExportFilter = dependency.getResourceExportFilter(); if ((resourceImportFilter == PathFilters.acceptAll() || resourceFilterStack.contains(resourceImportFilter)) && (resourceExportFilter == PathFilters.acceptAll() || resourceFilterStack.contains(resourceExportFilter))) { nestedResourceFilters = resourceFilterStack; } else { nestedResourceFilters = resourceFilterStack.clone(); if (resourceImportFilter != PathFilters.acceptAll()) nestedResourceFilters.add(resourceImportFilter); if (resourceExportFilter != PathFilters.acceptAll()) nestedResourceFilters.add(resourceExportFilter); } subtract += module.addExportedPaths(module.getDependenciesInternal(), map, nestedFilters, nestedClassFilters, nestedResourceFilters, visited); } else if (dependency instanceof ModuleClassLoaderDependency) { final ModuleClassLoaderDependency classLoaderDependency = (ModuleClassLoaderDependency) dependency; LocalLoader localLoader = classLoaderDependency.getLocalLoader(); for (Object filter : classFilterStack.getRawArray()) { if (filter != null && filter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader((ClassFilter) filter, localLoader); } } for (Object filter : resourceFilterStack.getRawArray()) { if (filter != null && filter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader((PathFilter) filter, localLoader); } } ClassFilter classImportFilter = classLoaderDependency.getClassImportFilter(); if (classImportFilter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader(classImportFilter, localLoader); } ClassFilter classExportFilter = classLoaderDependency.getClassExportFilter(); if (classExportFilter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader(classExportFilter, localLoader); } PathFilter resourceImportFilter = classLoaderDependency.getResourceImportFilter(); if (resourceImportFilter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader(resourceImportFilter, localLoader); } PathFilter resourceExportFilter = classLoaderDependency.getResourceExportFilter(); if (resourceExportFilter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader(resourceExportFilter, localLoader); } final PathFilter importFilter = classLoaderDependency.getImportFilter(); final Set paths = classLoaderDependency.getPaths(); for (String path : paths) { boolean accept = ! "_private".equals(path); if (accept) for (Object filter : filterStack.getRawArray()) { if (filter != null && ! ((PathFilter)filter).accept(path)) { accept = false; break; } } if (accept && importFilter.accept(path) && exportFilter.accept(path)) { List list = map.get(path); if (list == null) { map.put(path, list = new ArrayList(1)); list.add(localLoader); } else if (! list.contains(localLoader)) { list.add(localLoader); } } } } else if (dependency instanceof LocalDependency) { final LocalDependency localDependency = (LocalDependency) dependency; LocalLoader localLoader = localDependency.getLocalLoader(); for (Object filter : classFilterStack.getRawArray()) { if (filter != null && filter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader((ClassFilter) filter, localLoader); } } for (Object filter : resourceFilterStack.getRawArray()) { if (filter != null && filter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader((PathFilter) filter, localLoader); } } ClassFilter classFilter = localDependency.getClassExportFilter(); if (classFilter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader(classFilter, localLoader); } classFilter = localDependency.getClassImportFilter(); if (classFilter != ClassFilters.acceptAll()) { localLoader = createClassFilteredLocalLoader(classFilter, localLoader); } PathFilter resourceFilter = localDependency.getResourceExportFilter(); if (resourceFilter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader(resourceFilter, localLoader); } resourceFilter = localDependency.getResourceImportFilter(); if (resourceFilter != PathFilters.acceptAll()) { localLoader = createPathFilteredLocalLoader(resourceFilter, localLoader); } final Set paths = localDependency.getPaths(); for (String path : paths) { boolean accept = true; for (Object filter : filterStack.getRawArray()) { if (filter != null && ! ((PathFilter)filter).accept(path)) { accept = false; break; } } if (accept && localDependency.getImportFilter().accept(path) && localDependency.getExportFilter().accept(path)) { List list = map.get(path); if (list == null) { map.put(path, list = new ArrayList(1)); list.add(localLoader); } else if (! list.contains(localLoader)) { list.add(localLoader); } } } } // else unknown dep type so just skip } } return subtract; } Map> getPaths() throws ModuleLoadException { Linkage oldLinkage = this.linkage; Linkage linkage; Linkage.State state = oldLinkage.getState(); if (state == Linkage.State.LINKED) { return oldLinkage.getPaths(); } // slow path loop boolean intr = false; try { for (;;) { synchronized (this) { oldLinkage = this.linkage; state = oldLinkage.getState(); while (state == Linkage.State.LINKING || state == Linkage.State.NEW) try { wait(); oldLinkage = this.linkage; state = oldLinkage.getState(); } catch (InterruptedException e) { intr = true; } if (state == Linkage.State.LINKED) { return oldLinkage.getPaths(); } this.linkage = linkage = new Linkage(oldLinkage.getDependencySpecs(), oldLinkage.getDependencies(), Linkage.State.LINKING); // fall out and link } boolean ok = false; try { link(linkage); ok = true; } finally { if (! ok) { // restore original (lack of) linkage synchronized (this) { if (this.linkage == linkage) { this.linkage = oldLinkage; notifyAll(); } } } } } } finally { if (intr) { Thread.currentThread().interrupt(); } } } Map> getPathsUnchecked() { try { return getPaths(); } catch (ModuleLoadException e) { throw e.toError(); } } void link(final Linkage linkage) throws ModuleLoadException { final HashMap> importsMap = new HashMap>(); final Dependency[] dependencies = linkage.getDependencies(); final long start = Metrics.getCurrentCPUTime(); long subtractTime = 0L; try { final Set visited = new FastCopyHashSet(16); final FastCopyHashSet filterStack = new FastCopyHashSet(8); final FastCopyHashSet classFilterStack = EMPTY_CLASS_FILTERS; final FastCopyHashSet resourceFilterStack = EMPTY_PATH_FILTERS; subtractTime += addPaths(dependencies, importsMap, filterStack, classFilterStack, resourceFilterStack, visited); synchronized (this) { if (this.linkage == linkage) { this.linkage = new Linkage(linkage.getDependencySpecs(), linkage.getDependencies(), Linkage.State.LINKED, importsMap); notifyAll(); } // else all our efforts were just wasted since someone changed the deps in the meantime } } finally { moduleLoader.addLinkTime(Metrics.getCurrentCPUTime() - start - subtractTime); } } void relinkIfNecessary() throws ModuleLoadException { Linkage oldLinkage = this.linkage; Linkage linkage; if (oldLinkage.getState() != Linkage.State.UNLINKED) { return; } synchronized (this) { oldLinkage = this.linkage; if (oldLinkage.getState() != Linkage.State.UNLINKED) { return; } this.linkage = linkage = new Linkage(oldLinkage.getDependencySpecs(), oldLinkage.getDependencies(), Linkage.State.LINKING); } boolean ok = false; try { link(linkage); ok = true; } finally { if (! ok) { // restore original (lack of) linkage synchronized (this) { if (this.linkage == linkage) { this.linkage = oldLinkage; notifyAll(); } } } } } void relink() throws ModuleLoadException { link(linkage); } void setDependencies(final List dependencySpecs) { if (dependencySpecs == null) { throw new IllegalArgumentException("dependencySpecs is null"); } final DependencySpec[] specs = dependencySpecs.toArray(new DependencySpec[dependencySpecs.size()]); for (DependencySpec spec : specs) { if (spec == null) { throw new IllegalArgumentException("dependencySpecs contains a null dependency specification"); } } setDependencies(specs); } void setDependencies(final DependencySpec[] dependencySpecs) { synchronized (this) { linkage = new Linkage(dependencySpecs, calculateDependencies(dependencySpecs), Linkage.State.UNLINKED, null); notifyAll(); } } private Dependency[] calculateDependencies(final DependencySpec[] dependencySpecs) { final Dependency[] dependencies = new Dependency[dependencySpecs.length]; int i = 0; for (DependencySpec spec : dependencySpecs) { final Dependency dependency = spec.getDependency(this); dependencies[i++] = dependency; } return dependencies; } String getMainClass() { return mainClassName; } Package getPackage(final String name) { List loaders = getPathsUnchecked().get(name.replace('.', '/')); if (loaders != null) for (LocalLoader localLoader : loaders) { Package pkg = localLoader.loadPackageLocal(name); if (pkg != null) return pkg; } return null; } Package[] getPackages() { final ArrayList packages = new ArrayList(); final Map> allPaths = getPathsUnchecked(); next: for (String path : allPaths.keySet()) { String packageName = path.replace('/', '.'); for (LocalLoader loader : allPaths.get(path)) { Package pkg = loader.loadPackageLocal(packageName); if (pkg != null) { packages.add(pkg); } continue next; } } return packages.toArray(new Package[packages.size()]); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleClassLoader.java000066400000000000000000000711421257205723500275730ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.PermissionCollection; import java.security.ProtectionDomain; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.NoSuchElementException; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.log.ModuleLogger; import java.io.IOException; import java.io.InputStream; import java.lang.instrument.ClassFileTransformer; import java.net.URL; import java.security.CodeSource; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; /** * A module classloader. Instances of this class implement the complete view of classes and resources available in a * module. Contrast with {@link Module}, which has API methods to access the exported view of classes and resources. * * @author John Bailey * @author David M. Lloyd * @author thomas.diesler@jboss.com * * @apiviz.landmark */ public class ModuleClassLoader extends ConcurrentClassLoader { static { boolean parallelOk = true; try { parallelOk = ClassLoader.registerAsParallelCapable(); } catch (Throwable ignored) { } if (! parallelOk) { throw new Error("Failed to register " + ModuleClassLoader.class.getName() + " as parallel-capable"); } } static final ResourceLoaderSpec[] NO_RESOURCE_LOADERS = new ResourceLoaderSpec[0]; private final Module module; private final ClassFileTransformer transformer; private volatile Paths paths; private final LocalLoader localLoader = new IterableLocalLoader() { public Class loadClassLocal(final String name, final boolean resolve) { try { return ModuleClassLoader.this.loadClassLocal(name, resolve); } catch (ClassNotFoundException e) { final Throwable cause = e.getCause(); if (cause instanceof Error) { throw (Error) cause; } else if (cause instanceof RuntimeException) { //unlikely throw (RuntimeException) cause; } return null; } } public Package loadPackageLocal(final String name) { return findLoadedPackage(name); } public List loadResourceLocal(final String name) { return ModuleClassLoader.this.loadResourceLocal(name); } public Iterator iterateResources(final String startPath, final boolean recursive) { return ModuleClassLoader.this.iterateResources(startPath, recursive); } public String toString() { return "local loader for " + ModuleClassLoader.this.toString(); } }; private static final AtomicReferenceFieldUpdater> pathsUpdater = unsafeCast(AtomicReferenceFieldUpdater.newUpdater(ModuleClassLoader.class, Paths.class, "paths")); @SuppressWarnings({ "unchecked" }) private static AtomicReferenceFieldUpdater unsafeCast(AtomicReferenceFieldUpdater updater) { return (AtomicReferenceFieldUpdater) updater; } /** * Construct a new instance. * * @param configuration the module class loader configuration to use */ protected ModuleClassLoader(final Configuration configuration) { module = configuration.getModule(); paths = new Paths(configuration.getResourceLoaders(), Collections.>emptyMap()); final AssertionSetting setting = configuration.getAssertionSetting(); if (setting != AssertionSetting.INHERIT) { setDefaultAssertionStatus(setting == AssertionSetting.ENABLED); } transformer = configuration.getTransformer(); } /** * Recalculate the path maps for this module class loader. * * @return {@code true} if the paths were recalculated, or {@code false} if another thread finished recalculating * before the calling thread */ boolean recalculate() { final Paths paths = this.paths; return setResourceLoaders(paths, paths.getSourceList(NO_RESOURCE_LOADERS)); } /** * Change the set of resource loaders for this module class loader, and recalculate the path maps. * * @param resourceLoaders the new resource loaders * @return {@code true} if the paths were recalculated, or {@code false} if another thread finished recalculating * before the calling thread */ boolean setResourceLoaders(final ResourceLoaderSpec[] resourceLoaders) { return setResourceLoaders(paths, resourceLoaders); } private boolean setResourceLoaders(final Paths paths, final ResourceLoaderSpec[] resourceLoaders) { final Map> allPaths = new HashMap>(); for (ResourceLoaderSpec loaderSpec : resourceLoaders) { final ResourceLoader loader = loaderSpec.getResourceLoader(); final PathFilter filter = loaderSpec.getPathFilter(); for (String path : loader.getPaths()) { if (filter.accept(path)) { final List allLoaders = allPaths.get(path); if (allLoaders == null) { ArrayList newList = new ArrayList(16); newList.add(loader); allPaths.put(path, newList); } else { allLoaders.add(loader); } } } } return pathsUpdater.compareAndSet(this, paths, new Paths(resourceLoaders, allPaths)); } /** * Get the local loader which refers to this module class loader. * * @return the local loader */ LocalLoader getLocalLoader() { return localLoader; } /** {@inheritDoc} */ @Override protected final Class findClass(String className, boolean exportsOnly, final boolean resolve) throws ClassNotFoundException { // Check if we have already loaded it.. Class loadedClass = findLoadedClass(className); if (loadedClass != null) { if (resolve) { resolveClass(loadedClass); } return loadedClass; } final ModuleLogger log = Module.log; final Module module = this.module; log.trace("Finding class %s from %s", className, module); final Class clazz = module.loadModuleClass(className, resolve); if (clazz != null) { return clazz; } log.trace("Class %s not found from %s", className, module); throw new ClassNotFoundException(className + " from [" + module + "]"); } /** * Load a class from this class loader. * * @param className the class name to load * @return the loaded class or {@code null} if it was not found * @throws ClassNotFoundException if an exception occurs while loading the class or its dependencies */ public Class loadClassLocal(String className) throws ClassNotFoundException { return loadClassLocal(className, false); } /** * Load a local class from this class loader. * * @param className the class name * @param resolve {@code true} to resolve the loaded class * @return the loaded class or {@code null} if it was not found * @throws ClassNotFoundException if an error occurs while loading the class */ public Class loadClassLocal(final String className, final boolean resolve) throws ClassNotFoundException { final ModuleLogger log = Module.log; final Module module = this.module; log.trace("Finding local class %s from %s", className, module); // Check if we have already loaded it.. Class loadedClass = findLoadedClass(className); if (loadedClass != null) { log.trace("Found previously loaded %s from %s", loadedClass, module); if (resolve) { resolveClass(loadedClass); } return loadedClass; } final Map> paths = this.paths.getAllPaths(); log.trace("Loading class %s locally from %s", className, module); String pathOfClass = Module.pathOfClass(className); final List loaders = paths.get(pathOfClass); if (loaders == null) { // no loaders for this path return null; } // Check to see if we can define it locally it ClassSpec classSpec; ResourceLoader resourceLoader; try { if (loaders.size() > 0) { String fileName = Module.fileNameOfClass(className); for (ResourceLoader loader : loaders) { classSpec = loader.getClassSpec(fileName); if (classSpec != null) { resourceLoader = loader; try { preDefine(classSpec, className); } catch (Throwable th) { throw new ClassNotFoundException("Failed to preDefine class: " + className, th); } final Class clazz = defineClass(className, classSpec, resourceLoader); try { postDefine(classSpec, clazz); } catch (Throwable th) { throw new ClassNotFoundException("Failed to postDefine class: " + className, th); } if (resolve) { resolveClass(clazz); } return clazz; } } } } catch (IOException e) { throw new ClassNotFoundException(className, e); } catch (RuntimeException e) { log.trace(e, "Unexpected runtime exception in module loader"); throw new ClassNotFoundException(className, e); } catch (Error e) { log.trace(e, "Unexpected error in module loader"); throw e; } log.trace("No local specification found for class %s in %s", className, module); return null; } /** * Load a local resource from a specific root from this module class loader. * * @param root the root name * @param name the resource name * @return the resource, or {@code null} if it was not found */ Resource loadResourceLocal(final String root, final String name) { final Map> paths = this.paths.getAllPaths(); final String path = Module.pathOf(name); final List loaders = paths.get(path); if (loaders == null) { // no loaders for this path return null; } for (ResourceLoader loader : loaders) { if (root.equals(loader.getRootName())) { return loader.getResource(name); } } return null; } /** * Load a local resource from this class loader. * * @param name the resource name * @return the list of resources */ public List loadResourceLocal(final String name) { final Map> paths = this.paths.getAllPaths(); final String path = Module.pathOf(name); final List loaders = paths.get(path); if (loaders == null) { // no loaders for this path return Collections.emptyList(); } final List list = new ArrayList(loaders.size()); for (ResourceLoader loader : loaders) { final Resource resource = loader.getResource(name); if (resource != null) { list.add(resource); } } return list.isEmpty() ? Collections.emptyList() : list; } private Class doDefineOrLoadClass(final String className, final byte[] bytes, int off, int len, ProtectionDomain protectionDomain) { try { final Class definedClass = defineClass(className, bytes, off, len, protectionDomain); module.getModuleLoader().incClassCount(); return definedClass; } catch (LinkageError e) { final Class loadedClass = findLoadedClass(className); if (loadedClass != null) { module.getModuleLoader().incRaceCount(); return loadedClass; } throw e; } } private final IdentityHashMap protectionDomains = new IdentityHashMap(); private ProtectionDomain getProtectionDomain(CodeSource codeSource) { final IdentityHashMap map = protectionDomains; synchronized (map) { ProtectionDomain protectionDomain = map.get(codeSource); if (protectionDomain == null) { final PermissionCollection permissions = module.getPermissionCollection(); protectionDomain = new ProtectionDomain(codeSource, permissions); map.put(codeSource, protectionDomain); } return protectionDomain; } } /** * Define a class from a class name and class spec. Also defines any enclosing {@link Package} instances, * and performs any sealed-package checks. * * @param name the class name * @param classSpec the class spec * @param resourceLoader the resource loader of the class spec * @return the new class */ private Class defineClass(final String name, final ClassSpec classSpec, final ResourceLoader resourceLoader) { final ModuleLogger log = Module.log; final Module module = this.module; log.trace("Attempting to define class %s in %s", name, module); // Ensure that the package is loaded final int lastIdx = name.lastIndexOf('.'); if (lastIdx != -1) { // there's a package name; get the Package for it final String packageName = name.substring(0, lastIdx); synchronized (this) { Package pkg = findLoadedPackage(packageName); if (pkg == null) { try { pkg = definePackage(packageName, resourceLoader.getPackageSpec(packageName)); } catch (IOException e) { pkg = definePackage(packageName, null); } } // Check sealing if (pkg.isSealed() && ! pkg.isSealed(classSpec.getCodeSource().getLocation())) { log.trace("Detected a sealing violation (attempt to define class %s in sealed package %s in %s)", name, packageName, module); // use the same message as the JDK throw new SecurityException("sealing violation: package " + packageName + " is sealed"); } } } final Class newClass; try { byte[] bytes = classSpec.getBytes(); try { final ProtectionDomain protectionDomain = getProtectionDomain(classSpec.getCodeSource()); if (transformer != null) { try { bytes = transformer.transform(this, name.replace('.', '/'), null, protectionDomain, bytes); } catch (Exception e) { ClassFormatError error = new ClassFormatError(e.getMessage()); error.initCause(e); throw error; } } final long start = Metrics.getCurrentCPUTime(); newClass = doDefineOrLoadClass(name, bytes, 0, bytes.length, protectionDomain); module.getModuleLoader().addClassLoadTime(Metrics.getCurrentCPUTime() - start); log.classDefined(name, module); } catch (NoClassDefFoundError e) { // Prepend the current class name, so that transitive class definition issues are clearly expressed final LinkageError ne = new LinkageError("Failed to link " + name.replace('.', '/') + " (" + module + ")"); ne.initCause(e); throw ne; } } catch (Error e) { log.classDefineFailed(e, name, module); throw e; } catch (RuntimeException e) { log.classDefineFailed(e, name, module); throw e; } final AssertionSetting setting = classSpec.getAssertionSetting(); if (setting != AssertionSetting.INHERIT) { setClassAssertionStatus(name, setting == AssertionSetting.ENABLED); } return newClass; } /** * A hook which is invoked before a class is defined. * * @param classSpec the class spec of the defined class * @param className the class to be defined */ @SuppressWarnings("unused") protected void preDefine(ClassSpec classSpec, String className) { } /** * A hook which is invoked after a class is defined. * * @param classSpec the class spec of the defined class * @param definedClass the class that was defined */ @SuppressWarnings("unused") protected void postDefine(ClassSpec classSpec, Class definedClass) { } /** * Define a package from a package spec. * * @param name the package name * @param spec the package specification * @return the new package */ private Package definePackage(final String name, final PackageSpec spec) { final Module module = this.module; final ModuleLogger log = Module.log; log.trace("Attempting to define package %s in %s", name, module); final Package pkg; if (spec == null) { pkg = definePackage(name, null, null, null, null, null, null, null); } else { pkg = definePackage(name, spec.getSpecTitle(), spec.getSpecVersion(), spec.getSpecVendor(), spec.getImplTitle(), spec.getImplVersion(), spec.getImplVendor(), spec.getSealBase()); final AssertionSetting setting = spec.getAssertionSetting(); if (setting != AssertionSetting.INHERIT) { setPackageAssertionStatus(name, setting == AssertionSetting.ENABLED); } } log.trace("Defined package %s in %s", name, module); return pkg; } /** * Find a library from one of the resource loaders. * * @param libname the library name * @return the full absolute path to the library */ @Override protected final String findLibrary(final String libname) { final ModuleLogger log = Module.log; log.trace("Attempting to load native library %s from %s", libname, module); for (ResourceLoaderSpec loader : paths.getSourceList(NO_RESOURCE_LOADERS)) { final String library = loader.getResourceLoader().getLibrary(libname); if (library != null) { return library; } } return null; } /** {@inheritDoc} */ @Override public final URL findResource(final String name, final boolean exportsOnly) { return module.getResource(name); } /** {@inheritDoc} */ @Override public final Enumeration findResources(final String name, final boolean exportsOnly) throws IOException { return module.getResources(name); } /** {@inheritDoc} */ @Override public final InputStream findResourceAsStream(final String name, boolean exportsOnly) { try { return module.getResourceAsStream(name); } catch (IOException e) { return null; } } /** * Get the module for this class loader. * * @return the module */ public final Module getModule() { return module; } /** * Get a string representation of this class loader. * * @return the string */ @Override public final String toString() { return getClass().getSimpleName() + " for " + module; } Set getPaths() { return paths.getAllPaths().keySet(); } /** {@inheritDoc} */ @Override protected final Package definePackage(final String name, final String specTitle, final String specVersion, final String specVendor, final String implTitle, final String implVersion, final String implVendor, final URL sealBase) throws IllegalArgumentException { return super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase); } /** {@inheritDoc} */ @Override protected final Package getPackageByName(final String name) { Package loaded = findLoadedPackage(name); if (loaded != null) { return loaded; } return module.getPackage(name); } /** {@inheritDoc} */ @Override protected final Package[] getPackages() { return module.getPackages(); } /** {@inheritDoc} */ @Override public final void setDefaultAssertionStatus(final boolean enabled) { super.setDefaultAssertionStatus(enabled); } /** {@inheritDoc} */ @Override public final void setPackageAssertionStatus(final String packageName, final boolean enabled) { super.setPackageAssertionStatus(packageName, enabled); } /** {@inheritDoc} */ @Override public final void setClassAssertionStatus(final String className, final boolean enabled) { super.setClassAssertionStatus(className, enabled); } /** {@inheritDoc} */ @Override public final void clearAssertionStatus() { super.clearAssertionStatus(); } /** {@inheritDoc} */ @Override public final int hashCode() { return super.hashCode(); } /** {@inheritDoc} */ @Override public final boolean equals(final Object obj) { return super.equals(obj); } /** {@inheritDoc} */ @Override protected final Object clone() throws CloneNotSupportedException { return super.clone(); } /** {@inheritDoc} */ @Override protected final void finalize() throws Throwable { super.finalize(); } ResourceLoader[] getResourceLoaders() { final ResourceLoaderSpec[] specs = paths.getSourceList(NO_RESOURCE_LOADERS); final int length = specs.length; final ResourceLoader[] loaders = new ResourceLoader[length]; for (int i = 0; i < length; i++) { loaders[i] = specs[i].getResourceLoader(); } return loaders; } /** * Iterate the resources within this module class loader. Only resource roots which are inherently iterable will * be checked, thus the result of this method may only be a subset of the actual loadable resources. The returned * resources are not sorted or grouped in any particular way. * * @param startName the directory name to search * @param recurse {@code true} to recurse into subdirectories, {@code false} otherwise * @return the resource iterator */ public final Iterator iterateResources(final String startName, final boolean recurse) { final String realStartName = PathUtils.canonicalize(PathUtils.relativize(startName)); final PathFilter filter; if (recurse) { if (realStartName.isEmpty()) { filter = PathFilters.acceptAll(); } else { filter = PathFilters.any(PathFilters.is(realStartName), PathFilters.isChildOf(realStartName)); } } else { filter = PathFilters.is(realStartName); } final Map> paths = this.paths.getAllPaths(); final Iterator>> iterator = paths.entrySet().iterator(); return new Iterator() { private String path; private Iterator resourceIterator; private Iterator loaderIterator; private Resource next; public boolean hasNext() { while (next == null) { if (resourceIterator != null) { assert path != null; if (resourceIterator.hasNext()) { next = resourceIterator.next(); return true; } resourceIterator = null; } if (loaderIterator != null) { assert path != null; if (loaderIterator.hasNext()) { final ResourceLoader loader = loaderIterator.next(); if (loader instanceof IterableResourceLoader) { resourceIterator = ((IterableResourceLoader)loader).iterateResources(path, false); continue; } } loaderIterator = null; } if (! iterator.hasNext()) { return false; } final Map.Entry> entry = iterator.next(); path = entry.getKey(); if (filter.accept(path)) { loaderIterator = entry.getValue().iterator(); } } return true; } public Resource next() { if (! hasNext()) throw new NoSuchElementException(); try { return next; } finally { next = null; } } public void remove() { throw new UnsupportedOperationException(); } }; } /** * Get the (unmodifiable) set of paths which are locally available in this module class loader. The set will * include all paths defined by the module's resource loaders, minus any paths excluded by filters. The set will * generally always contain an empty entry (""). The set is unordered and unsorted, and is iterable in O(n) time * and accessible in O(1) time. * * @return the set of local paths */ public final Set getLocalPaths() { return Collections.unmodifiableSet(paths.getAllPaths().keySet()); } /** * An opaque configuration used internally to create a module class loader. * * @apiviz.exclude */ public static final class Configuration { private final Module module; private final AssertionSetting assertionSetting; private final ResourceLoaderSpec[] resourceLoaders; private final ClassFileTransformer transformer; Configuration(final Module module, final AssertionSetting assertionSetting, final ResourceLoaderSpec[] resourceLoaders, final ClassFileTransformer transformer) { this.module = module; this.assertionSetting = assertionSetting; this.resourceLoaders = resourceLoaders; this.transformer = transformer; } Module getModule() { return module; } AssertionSetting getAssertionSetting() { return assertionSetting; } ResourceLoaderSpec[] getResourceLoaders() { return resourceLoaders; } ClassFileTransformer getTransformer() { return transformer; } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleClassLoaderDependency.java000066400000000000000000000037471257205723500316000ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.Set; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.PathFilter; /** * @author David M. Lloyd */ final class ModuleClassLoaderDependency extends Dependency { private final ModuleClassLoader moduleClassLoader; ModuleClassLoaderDependency(final PathFilter exportFilter, final PathFilter importFilter, final ModuleClassLoader moduleClassLoader) { super(exportFilter, importFilter); this.moduleClassLoader = moduleClassLoader; } ModuleClassLoaderDependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter, final ModuleClassLoader moduleClassLoader) { super(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter); this.moduleClassLoader = moduleClassLoader; } LocalLoader getLocalLoader() { return moduleClassLoader.getLocalLoader(); } Set getPaths() { return moduleClassLoader.getPaths(); } public String toString() { return "dependency on " + moduleClassLoader; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleClassLoaderFactory.java000066400000000000000000000023401257205723500311150ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * A producer for Module class loaders. * * @author David M. Lloyd */ public interface ModuleClassLoaderFactory { /** * Create the module class loader. If this method returns {@code null}, then a default implementation is used. * * @param configuration the configuration to use * @return the module class loader, or {@code null} to use the default */ ModuleClassLoader create(ModuleClassLoader.Configuration configuration); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleDependency.java000066400000000000000000000044561257205723500274610ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.PathFilter; /** * @author David M. Lloyd */ final class ModuleDependency extends Dependency { private final ModuleLoader moduleLoader; private final ModuleIdentifier identifier; private final boolean optional; ModuleDependency(final PathFilter exportFilter, final PathFilter importFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) { super(exportFilter, importFilter); this.moduleLoader = moduleLoader; this.identifier = identifier; this.optional = optional; } ModuleDependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) { super(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter); this.moduleLoader = moduleLoader; this.identifier = identifier; this.optional = optional; } ModuleIdentifier getIdentifier() { return identifier; } boolean isOptional() { return optional; } ModuleLoader getModuleLoader() { return moduleLoader; } public String toString() { return (optional ? "optional " : "" ) + "dependency on " + identifier + " (" + moduleLoader + ")"; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleDependencySpec.java000066400000000000000000000052631257205723500302710ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.PathFilter; /** * A dependency specification on a module. */ public final class ModuleDependencySpec extends DependencySpec { private final ModuleLoader moduleLoader; private final ModuleIdentifier identifier; private final boolean optional; ModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) { super(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter); this.moduleLoader = moduleLoader; this.identifier = identifier; this.optional = optional; } Dependency getDependency(final Module module) { final ModuleLoader loader = moduleLoader; return new ModuleDependency(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter, loader == null ? module.getModuleLoader() : loader, identifier, optional); } /** * Get the module loader of this dependency, or {@code null} if the defined module's loader is to be used. * * @return the module loader */ public ModuleLoader getModuleLoader() { return moduleLoader; } /** * Get the module identifier of the dependency. * * @return the module identifier */ public ModuleIdentifier getIdentifier() { return identifier; } /** * Determine whether this dependency is optional. * * @return {@code true} if the dependency is optional, {@code false} if it is required */ public boolean isOptional() { return optional; } public String toString() { return "dependency on " + identifier; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleFinder.java000066400000000000000000000024601257205723500266030ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * A locator for module definitions. * * @author David M. Lloyd */ public interface ModuleFinder { /** * Find a module specification for the given identifier. * * @param identifier the module identifier * @param delegateLoader the module loader from which dependencies should be resolved * @return the module specification, or {@code null} if no specification is found for this identifier */ ModuleSpec findModule(ModuleIdentifier identifier, ModuleLoader delegateLoader) throws ModuleLoadException; } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleIdentifier.java000066400000000000000000000211751257205723500274620ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.lang.reflect.Field; import java.security.AccessController; import java.security.PrivilegedAction; /** * A unique identifier for a module within a module loader. * * @author John Bailey * @author David M. Lloyd * @author Jason T. Greene * * @apiviz.landmark */ public final class ModuleIdentifier implements Serializable { private static final long serialVersionUID = 118533026624827995L; private static final String DEFAULT_SLOT = "main"; private final String name; private final String slot; private final transient int hashCode; private static final Field hashField; static { hashField = AccessController.doPrivileged(new PrivilegedAction() { public Field run() { final Field field; try { field = ModuleIdentifier.class.getDeclaredField("hashCode"); field.setAccessible(true); } catch (NoSuchFieldException e) { throw new NoSuchFieldError(e.getMessage()); } return field; } }); } /** * The class path module (only present if booted from a class path). */ public static final ModuleIdentifier CLASSPATH = new ModuleIdentifier("Classpath", DEFAULT_SLOT); private ModuleIdentifier(final String name, final String slot) { this.name = name; this.slot = slot; hashCode = calculateHashCode(name, slot); } private static int calculateHashCode(final String name, final String slot) { int h = 17; h = 37 * h + name.hashCode(); h = 37 * h + slot.hashCode(); return h; } /** * Get the module name. * * @return the module name */ public String getName() { return name; } /** * Get the module version slot. * * @return the version slot */ public String getSlot() { return slot; } /** * Determine whether this object is equal to another. * * @param other the other object * @return {@code true} if they are equal, {@code false} otherwise */ public boolean equals(Object other) { return other instanceof ModuleIdentifier && equals((ModuleIdentifier)other); } /** * Determine whether this object is equal to another. * * @param other the other object * @return {@code true} if they are equal, {@code false} otherwise */ public boolean equals(ModuleIdentifier other) { return this == other || other != null && name.equals(other.name) && slot.equals(other.slot); } /** * Determine the hash code of this module identifier. * * @return the hash code */ @Override public int hashCode() { return hashCode; } /** * Get the string representation of this module identifier. * * @return the string representation */ @Override public String toString() { return escapeName(name) + ":" + escapeSlot(slot); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); try { hashField.setInt(this, calculateHashCode(name, slot)); } catch (IllegalAccessException e) { throw new IllegalAccessError(e.getMessage()); } } private static String escapeName(String name) { final StringBuilder b = new StringBuilder(); boolean escaped = false; int c; for (int i = 0; i < name.length(); i = name.offsetByCodePoints(i, 1)) { c = name.codePointAt(i); switch (c) { case '\\': case ':': escaped = true; b.append('\\'); // fall thru default: b.appendCodePoint(c); } } return escaped ? b.toString() : name; } private static String escapeSlot(String slot) { final StringBuilder b = new StringBuilder(); boolean escaped = false; int c; for (int i = 0; i < slot.length(); i = slot.offsetByCodePoints(i, 1)) { c = slot.codePointAt(i); switch (c) { case '\\': escaped = true; b.append('\\'); // fall thru default: b.appendCodePoint(c); } } return escaped ? b.toString() : slot; } /** * Parse a module specification from a string. * * @param moduleSpec the specification string * @return the module identifier * @throws IllegalArgumentException if the format of the module specification is invalid or it is {@code null} */ public static ModuleIdentifier fromString(String moduleSpec) throws IllegalArgumentException { if (moduleSpec == null) { throw new IllegalArgumentException("Module specification is null"); } if (moduleSpec.length() == 0) { throw new IllegalArgumentException("Empty module specification"); } int c; final StringBuilder b = new StringBuilder(); int i = 0; while (i < moduleSpec.length()) { c = moduleSpec.codePointAt(i); if (c == '\\') { b.appendCodePoint(c); i = moduleSpec.offsetByCodePoints(i, 1); if (i < moduleSpec.length()) { c = moduleSpec.codePointAt(i); b.appendCodePoint(c); } else { throw new IllegalArgumentException("Name has an unterminated escape"); } } else if (c == ':') { i = moduleSpec.offsetByCodePoints(i, 1); if (i == moduleSpec.length()) { throw new IllegalArgumentException("Slot is empty"); } // end of name, now comes the slot break; } else { b.appendCodePoint(c); } i = moduleSpec.offsetByCodePoints(i, 1); } final String name = b.toString(); b.setLength(0); if (i < moduleSpec.length()) do { c = moduleSpec.codePointAt(i); b.appendCodePoint(c); i = moduleSpec.offsetByCodePoints(i, 1); } while (i < moduleSpec.length()); else { return new ModuleIdentifier(name, DEFAULT_SLOT); } return new ModuleIdentifier(name, b.toString()); } /** * Creates a new module identifier using the specified name and slot. * A slot allows for multiple modules to exist with the same name. * The main usage pattern for this is to differentiate between * two incompatible release streams of a module. * * Normally all module definitions wind up in the "main" slot. * An unspecified or null slot will result in placement in the "main" * slot. * * Unless you have a true need for a slot, it should not be specified. * When in doubt use the {{@link #create(String)} method instead. * * @param name the name of the module * @param slot the slot this module belongs in * @return the identifier */ public static ModuleIdentifier create(final String name, String slot) { if (name == null) throw new IllegalArgumentException("Name can not be null"); if (slot == null) slot = DEFAULT_SLOT; return new ModuleIdentifier(name, slot); } /** * Creates a new module identifier using the specified name. * * @param name the name of the module * @return the identifier */ public static ModuleIdentifier create(String name) { return create(name, null); } }jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleLoadError.java000066400000000000000000000051361257205723500272700ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * Module load error, thrown when there is some problem loading a module during runtime. * * @author David M. Lloyd */ public class ModuleLoadError extends Error { private static final long serialVersionUID = 3286005346300416890L; /** * Constructs a {@code ModuleLoadException} with no detail message. The cause is not initialized, and may subsequently * be initialized by a call to {@link #initCause(Throwable) initCause}. */ public ModuleLoadError() { } /** * Constructs a {@code ModuleLoadException} with the specified detail message. The cause is not initialized, and may * subsequently be initialized by a call to {@link #initCause(Throwable) initCause}. * * @param msg the detail message */ public ModuleLoadError(final String msg) { super(msg); } /** * Constructs a {@code ModuleLoadException} with the specified cause. The detail message is set to: *

(cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}). * * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) */ public ModuleLoadError(final Throwable cause) { super(cause); } /** * Constructs a {@code ModuleLoadException} with the specified detail message and cause. * * @param msg the detail message * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) */ public ModuleLoadError(final String msg, final Throwable cause) { super(msg, cause); } /** * Convert to a checked exception type. * * @return the checked exception */ public ModuleLoadException toException() { return new ModuleLoadException(getMessage(), getCause()); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleLoadException.java000066400000000000000000000051341257205723500301330ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * Module load exception, thrown when there is some problem loading a module. * * @author David M. Lloyd */ public class ModuleLoadException extends Exception { private static final long serialVersionUID = 3286005346300416890L; /** * Constructs a {@code ModuleLoadException} with no detail message. The cause is not initialized, and may subsequently * be initialized by a call to {@link #initCause(Throwable) initCause}. */ public ModuleLoadException() { } /** * Constructs a {@code ModuleLoadException} with the specified detail message. The cause is not initialized, and may * subsequently be initialized by a call to {@link #initCause(Throwable) initCause}. * * @param msg the detail message */ public ModuleLoadException(final String msg) { super(msg); } /** * Constructs a {@code ModuleLoadException} with the specified cause. The detail message is set to: *
(cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}). * * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) */ public ModuleLoadException(final Throwable cause) { super(cause); } /** * Constructs a {@code ModuleLoadException} with the specified detail message and cause. * * @param msg the detail message * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) */ public ModuleLoadException(final String msg, final Throwable cause) { super(msg, cause); } /** * Convert to an unchecked error type. * * @return the unchecked error */ public ModuleLoadError toError() { return new ModuleLoadError(getMessage(), getCause()); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleLoader.java000066400000000000000000001245421257205723500266100ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static java.security.AccessController.doPrivileged; import static org.jboss.modules.management.ObjectProperties.property; import java.lang.management.ManagementFactory; import java.lang.reflect.UndeclaredThrowableException; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicLongFieldUpdater; import org.jboss.modules.log.ModuleLogger; import org.jboss.modules.management.DependencyInfo; import org.jboss.modules.management.ModuleInfo; import org.jboss.modules.management.ModuleLoaderMXBean; import org.jboss.modules.management.ObjectProperties; import org.jboss.modules.management.ResourceLoaderInfo; import org.jboss.modules.ref.Reaper; import org.jboss.modules.ref.Reference; import org.jboss.modules.ref.WeakReference; import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; /** * A repository for modules, from which a module may be loaded by identifier. Module loaders may additionally * delegate to one or more other module loaders. * * @author David M. Lloyd * @author John Bailey * @author Jason T. Greene * * @apiviz.landmark */ public class ModuleLoader { private static final RuntimePermission ML_PERM = new RuntimePermission("canCreateModuleLoader"); private static final RuntimePermission MODULE_REDEFINE_PERM = new RuntimePermission("canRedefineModule"); private static final RuntimePermission MODULE_REDEFINE_ANY_PERM = new RuntimePermission("canRedefineAnyModule"); private static final RuntimePermission MODULE_UNLOAD_ANY_PERM = new RuntimePermission("canUnloadAnyModule"); private static final RuntimePermission MODULE_ITERATE_PERM = new RuntimePermission("canIterateModules"); private static final AtomicInteger SEQ = new AtomicInteger(1); private static volatile MBeanReg REG_REF = new TempMBeanReg(); /** * A constant representing zero module finders. */ public static final ModuleFinder[] NO_FINDERS = new ModuleFinder[0]; private final ConcurrentMap moduleMap = new UnlockedReadHashMap(256); private final ModuleFinder[] finders; private final boolean canRedefine; private final ModuleLoaderMXBean mxBean; @SuppressWarnings({"unused", "VolatileLongOrDoubleField"}) private volatile long linkTime; @SuppressWarnings({"unused", "VolatileLongOrDoubleField"}) private volatile long loadTime; @SuppressWarnings({"unused", "VolatileLongOrDoubleField"}) private volatile long classLoadTime; @SuppressWarnings("unused") private volatile int scanCount; @SuppressWarnings("unused") private volatile int raceCount; @SuppressWarnings("unused") private volatile int classCount; private static final AtomicLongFieldUpdater linkTimeUpdater = AtomicLongFieldUpdater.newUpdater(ModuleLoader.class, "linkTime"); private static final AtomicLongFieldUpdater loadTimeUpdater = AtomicLongFieldUpdater.newUpdater(ModuleLoader.class, "loadTime"); private static final AtomicLongFieldUpdater classLoadTimeUpdater = AtomicLongFieldUpdater.newUpdater(ModuleLoader.class, "classLoadTime"); private static final AtomicIntegerFieldUpdater scanCountUpdater = AtomicIntegerFieldUpdater.newUpdater(ModuleLoader.class, "scanCount"); private static final AtomicIntegerFieldUpdater raceCountUpdater = AtomicIntegerFieldUpdater.newUpdater(ModuleLoader.class, "raceCount"); private static final AtomicIntegerFieldUpdater classCountUpdater = AtomicIntegerFieldUpdater.newUpdater(ModuleLoader.class, "classCount"); ModuleLoader(boolean canRedefine, boolean skipRegister) { this(canRedefine, skipRegister, NO_FINDERS); } // Bypass security check for classes in this package ModuleLoader(boolean canRedefine, boolean skipRegister, ModuleFinder[] finders) { this.canRedefine = canRedefine; this.finders = finders; mxBean = skipRegister ? null : doPrivileged(new PrivilegedAction() { public ModuleLoaderMXBean run() { ObjectName objectName; try { objectName = new ObjectName("jboss.modules", ObjectProperties.properties(property("type", "ModuleLoader"), property("name", ModuleLoader.this.getClass().getSimpleName() + "-" + Integer.toString(SEQ.incrementAndGet())))); } catch (MalformedObjectNameException e) { return null; } try { MXBeanImpl mxBean = new MXBeanImpl(ModuleLoader.this, objectName); REG_REF.addMBean(objectName, mxBean); return mxBean; } catch (Throwable ignored) { } return null; } }); } /** * Construct a new instance. */ protected ModuleLoader() { this(NO_FINDERS); } /** * Construct a new instance. * * @param finders the module finders to search, in order */ public ModuleLoader(final ModuleFinder[] finders) { this(checkPermissions(), false, safeClone(finders)); } private static ModuleFinder[] safeClone(ModuleFinder[] finders) { if (finders == null || finders.length == 0) { return NO_FINDERS; } finders = finders.clone(); for (ModuleFinder finder : finders) { if (finder == null) { throw new IllegalArgumentException("Module finder cannot be null"); } } return finders; } private static boolean checkPermissions() { SecurityManager manager = System.getSecurityManager(); if (manager == null) { return true; } manager.checkPermission(ML_PERM); try { manager.checkPermission(MODULE_REDEFINE_PERM); return true; } catch (SecurityException e) { return false; } } /** * Get the module loader for a class. * * @param clazz the class * * @return the module loader or {@code null} if the class's class loader does not belong to a module loader. */ public static ModuleLoader forClass(Class clazz) { final Module module = Module.forClass(clazz); if (module == null) { return null; } return module.getModuleLoader(); } /** * Get the module loader for a class loader. * * @param classLoader the class loader * * @return the module loader or {@code null} if the class loader does not belong to a module loader. */ public static ModuleLoader forClassLoader(ClassLoader classLoader) { final Module module = Module.forClassLoader(classLoader, true); if (module == null) { return null; } return module.getModuleLoader(); } /** * Get the string representation of this module loader. * * @return the string representation */ public String toString() { return String.format("%s@%x for finders %s", getClass().getSimpleName(), hashCode(), Arrays.toString(finders)); } static void installMBeanServer() { REG_REF.installReal(); } /** * Load a module based on an identifier. This method delegates to {@link #preloadModule(ModuleIdentifier)} and then * links the returned module if necessary. * * @param identifier The module identifier * @return The loaded Module * @throws ModuleLoadException if the Module can not be loaded */ public final Module loadModule(ModuleIdentifier identifier) throws ModuleLoadException { final Module module = preloadModule(identifier); if (module == null) { throw new ModuleNotFoundException(identifier.toString()); } module.relinkIfNecessary(); return module; } /** * Iterate the modules which can be located via this module loader. * * @param baseIdentifier the identifier to start with, or {@code null} to iterate all modules * @param recursive {@code true} to find recursively nested modules, {@code false} to only find immediately nested modules * @return an iterator for the modules in this module finder * @throws SecurityException if the caller does not have permission to iterate module loaders */ public final Iterator iterateModules(final ModuleIdentifier baseIdentifier, final boolean recursive) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(MODULE_ITERATE_PERM); } return new Iterator() { int idx; Iterator nested; public boolean hasNext() { for (;;) { while (nested == null) { if (idx == finders.length) { return false; } final ModuleFinder finder = finders[idx++]; if (finder instanceof IterableModuleFinder) { nested = ((IterableModuleFinder) finder).iterateModules(baseIdentifier, recursive); } } if (! nested.hasNext()) { nested = null; } else { return true; } } } public ModuleIdentifier next() { if (! hasNext()) { throw new NoSuchElementException(); } return nested.next(); } public void remove() { throw new UnsupportedOperationException(); } }; } /** * Preload a module based on an identifier. By default, no delegation is done and this method simply invokes * {@link #loadModuleLocal(ModuleIdentifier)}. A delegating module loader may delegate to the appropriate module * loader based on loader-specific criteria (via the {@link #preloadModule(ModuleIdentifier, ModuleLoader)} method). * * @param identifier the module identifier * @return the load result, or {@code null} if the module is not found * @throws ModuleLoadException if an error occurs */ protected Module preloadModule(ModuleIdentifier identifier) throws ModuleLoadException { return loadModuleLocal(identifier); } /** * Preload an "exported" module based on an identifier. By default this simply delegates to {@link #preloadModule(ModuleIdentifier)}. * * @param identifier the module identifier * @return the load result, or {@code null} if the module is not found * @throws ModuleLoadException if an error occurs */ protected Module preloadExportedModule(ModuleIdentifier identifier) throws ModuleLoadException { return preloadModule(identifier); } /** * Utility method to delegate to another module loader, accessible from subclasses. The delegate module loader * will be queried for exported modules only. * * @param identifier the module identifier * @param moduleLoader the module loader to delegate to * @return the delegation result * @throws ModuleLoadException if an error occurs */ protected static Module preloadModule(ModuleIdentifier identifier, ModuleLoader moduleLoader) throws ModuleLoadException { return moduleLoader.preloadExportedModule(identifier); } /** * Try to load a module from this module loader. Returns {@code null} if the module is not found. The returned * module may not yet be resolved. The returned module may have a different name than the given identifier if * the identifier is an alias for another module. * * @param identifier the module identifier * @return the module * @throws ModuleLoadException if an error occurs while loading the module */ protected final Module loadModuleLocal(ModuleIdentifier identifier) throws ModuleLoadException { FutureModule futureModule = moduleMap.get(identifier); if (futureModule != null) { return futureModule.getModule(); } FutureModule newFuture = new FutureModule(identifier); futureModule = moduleMap.putIfAbsent(identifier, newFuture); if (futureModule != null) { return futureModule.getModule(); } boolean ok = false; try { final ModuleLogger log = Module.log; log.trace("Locally loading module %s from %s", identifier, this); final long startTime = Metrics.getCurrentCPUTime(); final ModuleSpec moduleSpec = findModule(identifier); loadTimeUpdater.addAndGet(this, Metrics.getCurrentCPUTime() - startTime); if (moduleSpec == null) { log.trace("Module %s not found from %s", identifier, this); return null; } if (! moduleSpec.getModuleIdentifier().equals(identifier)) { throw new ModuleLoadException("Module loader found a module with the wrong name"); } final Module module; if ( moduleSpec instanceof AliasModuleSpec) { final ModuleIdentifier aliasTarget = ((AliasModuleSpec) moduleSpec).getAliasTarget(); try { newFuture.setModule(module = loadModuleLocal(aliasTarget)); } catch (RuntimeException e) { log.trace(e, "Failed to load module %s (alias for %s)", identifier, aliasTarget); throw e; } catch (Error e) { log.trace(e, "Failed to load module %s (alias for %s)", identifier, aliasTarget); throw e; } } else { module = defineModule((ConcreteModuleSpec) moduleSpec, newFuture); } log.trace("Loaded module %s from %s", identifier, this); ok = true; return module; } finally { if (! ok) { newFuture.setModule(null); moduleMap.remove(identifier, newFuture); } } } /** * Find an already-loaded module, returning {@code null} if the module isn't currently loaded. May block * while the loaded state of the module is in question (if the module is being concurrently loaded from another * thread, for example). * * @param identifier the module identifier * @return the module, or {@code null} if it wasn't found */ protected final Module findLoadedModuleLocal(ModuleIdentifier identifier) { FutureModule futureModule = moduleMap.get(identifier); if (futureModule != null) { try { return futureModule.getModule(); } catch (ModuleNotFoundException e) { return null; } } else { return null; } } /** * Unload a module from this module loader. Note that this has no effect on existing modules which refer to the * module being unloaded. Also, only modules from the current module loader can be unloaded. Unloading the same * module more than once has no additional effect. This method only removes the mapping for the module; any running * threads which are currently accessing or linked to the module will continue to function, however attempts to load * this module will fail until a new module is loaded with the same name. Once this happens, if all references to * the previous module are not cleared, the same module may be loaded more than once, causing possible class duplication * and class cast exceptions if proper care is not taken. * * @param module the module to unload * @throws SecurityException if an attempt is made to unload a module which does not belong to this module loader * @throws SecurityException if the module was not defined by this module loader */ protected final void unloadModuleLocal(Module module) throws SecurityException { final ModuleLoader moduleLoader = module.getModuleLoader(); if (moduleLoader != this) { throw new SecurityException("Attempted to unload " + module + " from a different module loader"); } final ModuleIdentifier id = module.getIdentifier(); final FutureModule futureModule = moduleMap.get(id); if (futureModule.module == module) { moduleMap.remove(id, futureModule); } } /** * Find a Module's specification in this ModuleLoader by its identifier. This can be overriden by sub-classes to * implement the Module loading strategy for this loader. The default implementation iterates the module finders * provided during construction. *

* If no module is found in this module loader with the given identifier, then this method should return {@code * null}. If the module is found but some problem occurred (for example, a transitive dependency failed to load) * then this method should throw a {@link ModuleLoadException} of the relevant type. * * @param moduleIdentifier the module identifier * @return the module specification, or {@code null} if no module is found with the given identifier * @throws ModuleLoadException if any problems occur finding the module */ protected ModuleSpec findModule(final ModuleIdentifier moduleIdentifier) throws ModuleLoadException { for (ModuleFinder finder : finders) { if (finder != null) { final ModuleSpec spec = finder.findModule(moduleIdentifier, this); if (spec != null) { return spec; } } } return null; } /** * Get the module finders configured for this module loader. * * @return the module finders */ protected final ModuleFinder[] getFinders() { return finders.length > 0 ? finders.clone() : NO_FINDERS; } /** * Defines a Module based on a specification. May only be called from {@link #loadModuleLocal(ModuleIdentifier)}. * * @param moduleSpec The module specification to create the Module from * @param futureModule the future module to populate * @return The defined Module * @throws ModuleLoadException If any dependent modules can not be loaded */ private Module defineModule(final ConcreteModuleSpec moduleSpec, final FutureModule futureModule) throws ModuleLoadException { try { return doPrivileged(new PrivilegedExceptionAction() { public Module run() throws Exception { final ModuleLogger log = Module.log; final ModuleIdentifier moduleIdentifier = moduleSpec.getModuleIdentifier(); final Module module = new Module(moduleSpec, ModuleLoader.this); module.getClassLoaderPrivate().recalculate(); module.setDependencies(moduleSpec.getDependenciesInternal()); log.moduleDefined(moduleIdentifier, ModuleLoader.this); try { futureModule.setModule(module); return module; } catch (RuntimeException e) { log.trace(e, "Failed to load module %s", moduleIdentifier); throw e; } catch (Error e) { log.trace(e, "Failed to load module %s", moduleIdentifier); throw e; } } }); } catch (PrivilegedActionException pe) { try { throw pe.getException(); } catch (RuntimeException e) { throw e; } catch (ModuleLoadException e) { throw e; } catch (Exception e) { throw new UndeclaredThrowableException(e); } } } /** * Refreshes the paths provided by resource loaders associated with the * specified Module. This is an advanced method that is intended to be * called on modules that have a resource loader implementation that has * changed and is returning different paths. * * @param module the module to refresh * @throws SecurityException if the module was not defined by this module loader, or if the module loader does not * have the required permissions associated with it */ protected void refreshResourceLoaders(Module module) { if (! canRedefine) { throw new SecurityException("Module redefinition requires canRedefineModule permission"); } if (module.getModuleLoader() != this) { throw new SecurityException("Module is not defined by this module loader"); } module.getClassLoaderPrivate().recalculate(); } /** * Replaces the resources loaders for the specified module and refreshes the * internal path list that is derived from the loaders. This is an advanced * method that should be used carefully, since it alters a live module. * Modules that import resources from the specified module will not * automatically be updated to reflect the change. For this to occur * {@link #relink(Module)} must be called on all of them. * * @param module the module to update and refresh * @param loaders the new collection of loaders the module should use * @throws SecurityException if the module was not defined by this module loader, or if the module loader does not * have the required permissions associated with it */ protected void setAndRefreshResourceLoaders(Module module, Collection loaders) { if (! canRedefine) { throw new SecurityException("Module redefinition requires canRedefineModule permission"); } if (module.getModuleLoader() != this) { throw new SecurityException("Module is not defined by this module loader"); } module.getClassLoaderPrivate().setResourceLoaders(loaders.toArray(new ResourceLoaderSpec[loaders.size()])); } /** * Relinks the dependencies associated with the specified Module. This is an * advanced method that is intended to be called on all modules that * directly or indirectly import dependencies that are re-exported by a module * that has recently been updated and relinked via * {@link #setAndRelinkDependencies(Module, java.util.List)}. * * @param module the module to relink * @throws ModuleLoadException if relinking failed * @throws SecurityException if the module was not defined by this module loader, or if the module loader does not * have the required permissions associated with it */ protected void relink(Module module) throws ModuleLoadException { if (! canRedefine) { throw new SecurityException("Module redefinition requires canRedefineModule permission"); } if (module.getModuleLoader() != this) { throw new SecurityException("Module is not defined by this module loader"); } module.relink(); } /** * Replaces the dependencies for the specified module and relinks against * the new modules This is an advanced method that should be used carefully, * since it alters a live module. Modules that import dependencies that are * re-exported from the specified module will not automatically be updated * to reflect the change. For this to occur {@link #relink(Module)} must be * called on all of them. * * @param module the module to update and relink * @param dependencies the new dependency list * @throws ModuleLoadException if relinking failed * @throws SecurityException if the module was not defined by this module loader, or if the module loader does not * have the required permissions associated with it */ protected void setAndRelinkDependencies(Module module, List dependencies) throws ModuleLoadException { if (! canRedefine) { throw new SecurityException("Module redefinition requires canRedefineModule permission"); } if (module.getModuleLoader() != this) { throw new SecurityException("Module is not defined by this module loader"); } module.setDependencies(dependencies); module.relinkIfNecessary(); } /** * Get the current dependency list for a module which was defined by this module loader, without any access checks. * * @return the current dependency list for the module * @throws SecurityException if the module was not defined by this module loader */ protected DependencySpec[] getDependencies(Module module) { if (module.getModuleLoader() != this) { throw new SecurityException("Module is not defined by this module loader"); } return module.getDependencySpecsInternal().clone(); } void addLinkTime(long amount) { if (amount != 0L) linkTimeUpdater.addAndGet(this, amount); } void addClassLoadTime(final long time) { if (time != 0L) classLoadTimeUpdater.addAndGet(this, time); } void incScanCount() { if (Metrics.ENABLED) scanCountUpdater.getAndIncrement(this); } void incRaceCount() { if (Metrics.ENABLED) raceCountUpdater.getAndIncrement(this); } void incClassCount() { if (Metrics.ENABLED) classCountUpdater.getAndIncrement(this); } private static final class FutureModule { private static final Object NOT_FOUND = new Object(); private final ModuleIdentifier identifier; private volatile Object module; FutureModule(final ModuleIdentifier identifier) { this.identifier = identifier; } Module getModule() throws ModuleNotFoundException { boolean intr = false; try { Object module = this.module; if (module == null) synchronized (this) { while ((module = this.module) == null) { try { wait(); } catch (InterruptedException e) { intr = true; } } } if (module == NOT_FOUND) throw new ModuleNotFoundException(identifier.toString()); return (Module) module; } finally { if (intr) Thread.currentThread().interrupt(); } } void setModule(Module m) { synchronized (this) { module = m == null ? NOT_FOUND : m; notifyAll(); } } } private static final Reaper reaper = new Reaper() { public void reap(final Reference reference) { REG_REF.removeMBean(reference.getAttachment()); } }; static final class MXBeanImpl implements ModuleLoaderMXBean { private final Reference reference; MXBeanImpl(final ModuleLoader moduleLoader, final ObjectName objectName) { reference = new WeakReference(moduleLoader, objectName, reaper); } public String getDescription() { return getModuleLoader().toString(); } public long getLinkTime() { return getModuleLoader().linkTime; } public long getLoadTime() { return getModuleLoader().loadTime; } public long getClassDefineTime() { return getModuleLoader().classLoadTime; } public int getScanCount() { return getModuleLoader().scanCount; } public int getLoadedModuleCount() { return getModuleLoader().moduleMap.size(); } public int getRaceCount() { return getModuleLoader().raceCount; } public int getClassCount() { return getModuleLoader().classCount; } public List queryLoadedModuleNames() { ModuleLoader loader = getModuleLoader(); final Set identifiers = loader.moduleMap.keySet(); final ArrayList list = new ArrayList(identifiers.size()); for (ModuleIdentifier identifier : identifiers) { list.add(identifier.toString()); } Collections.sort(list); return list; } public String dumpAllModuleInformation() { final StringBuilder b = new StringBuilder(); for (String name : queryLoadedModuleNames()) { doDumpModuleInformation(name, b); } return b.toString(); } public String dumpModuleInformation(final String name) { final StringBuilder b = new StringBuilder(); doDumpModuleInformation(name, b); return b.toString(); } private void doDumpModuleInformation(final String name, final StringBuilder b) { ModuleInfo description = getModuleDescription(name); b.append("Module ").append(name).append('\n'); b.append(" Class loader: ").append(description.getClassLoader()).append('\n'); String fallbackLoader = description.getFallbackLoader(); if (fallbackLoader != null) b.append(" Fallback loader: ").append(fallbackLoader).append('\n'); String mainClass = description.getMainClass(); if (mainClass != null) b.append(" Main Class: ").append(mainClass).append('\n'); List loaders = description.getResourceLoaders(); b.append(" Resource Loaders:\n"); for (ResourceLoaderInfo loader : loaders) { b.append(" Loader Type: ").append(loader.getType()).append('\n'); b.append(" Paths:\n"); for (String path : loader.getPaths()) { b.append(" ").append(path).append('\n'); } } b.append(" Dependencies:\n"); for (DependencyInfo dependencyInfo : description.getDependencies()) { b.append(" Type: ").append(dependencyInfo.getDependencyType()).append('\n'); String moduleName = dependencyInfo.getModuleName(); if (moduleName != null) { b.append(" Module Name: ").append(moduleName).append('\n'); } if (dependencyInfo.isOptional()) b.append(" (optional)\n"); b.append(" Export Filter: ").append(dependencyInfo.getExportFilter()).append('\n'); b.append(" Import Filter: ").append(dependencyInfo.getImportFilter()).append('\n'); String localLoader = dependencyInfo.getLocalLoader(); if (localLoader != null) { b.append(" Local Loader: ").append(localLoader).append('\n'); b.append(" Paths:\n"); for (String path : dependencyInfo.getLocalLoaderPaths()) { b.append(" ").append(path).append('\n'); } } } } public boolean unloadModule(final String name) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(MODULE_UNLOAD_ANY_PERM); } final ModuleLoader loader = getModuleLoader(); final Module module = loader.findLoadedModuleLocal(ModuleIdentifier.fromString(name)); if (module == null) { return false; } else { loader.unloadModuleLocal(module); return true; } } public void refreshResourceLoaders(final String name) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(MODULE_REDEFINE_ANY_PERM); } final ModuleLoader loader = getModuleLoader(); final Module module = loadModule(name, loader); loader.refreshResourceLoaders(module); } public void relink(final String name) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(MODULE_REDEFINE_ANY_PERM); } final ModuleLoader loader = getModuleLoader(); final Module module = loadModule(name, loader); try { loader.relink(module); } catch (ModuleLoadException e) { throw new IllegalStateException("Module load failure for module " + name + ": " + e.toString()); } } public List getDependencies(final String name) { final ModuleLoader loader = getModuleLoader(); final Module module = loadModule(name, loader); return doGetDependencies(module); } private List doGetDependencies(final Module module) { Dependency[] dependencies = module.getDependenciesInternal(); if (dependencies == null) { return Collections.emptyList(); } ArrayList list = new ArrayList(dependencies.length); for (Dependency dependency : dependencies) { final String dependencyType = dependency.getClass().getSimpleName(); final String exportFilter = dependency.getExportFilter().toString(); final String importFilter = dependency.getImportFilter().toString(); final DependencyInfo info; if (dependency instanceof LocalDependency) { final LocalDependency localDependency = (LocalDependency) dependency; ArrayList pathList = new ArrayList(localDependency.getPaths()); Collections.sort(pathList); info = new DependencyInfo(dependencyType, exportFilter, importFilter, null, null, false, localDependency.getLocalLoader().toString(), pathList); } else if (dependency instanceof ModuleDependency) { final ModuleDependency moduleDependency = (ModuleDependency) dependency; info = new DependencyInfo(dependencyType, exportFilter, importFilter, moduleDependency.getModuleLoader().mxBean, moduleDependency.getIdentifier().toString(), moduleDependency.isOptional(), null, null); } else { info = new DependencyInfo(dependencyType, exportFilter, importFilter, null, null, false, null, null); } list.add(info); } return list; } public List getResourceLoaders(final String name) { ModuleLoader loader = getModuleLoader(); final Module module = loadModule(name, loader); return doGetResourceLoaders(module); } private List doGetResourceLoaders(final Module module) { final ModuleClassLoader classLoader = module.getClassLoaderPrivate(); final ResourceLoader[] loaders = classLoader.getResourceLoaders(); final ArrayList list = new ArrayList(loaders.length); for (ResourceLoader resourceLoader : loaders) { list.add(new ResourceLoaderInfo(resourceLoader.getClass().getName(), new ArrayList(resourceLoader.getPaths()))); } return list; } public ModuleInfo getModuleDescription(final String name) { ModuleLoader loader = getModuleLoader(); final Module module = loadModule(name, loader); final List dependencies = doGetDependencies(module); final List resourceLoaders = doGetResourceLoaders(module); final LocalLoader fallbackLoader = module.getFallbackLoader(); final String fallbackLoaderString = fallbackLoader == null ? null : fallbackLoader.toString(); return new ModuleInfo(module.getIdentifier().toString(), module.getModuleLoader().mxBean, dependencies, resourceLoaders, module.getMainClass(), module.getClassLoaderPrivate().toString(), fallbackLoaderString); } public SortedMap> getModulePathsInfo(final String name, final boolean exports) { ModuleLoader loader = getModuleLoader(); final Module module = loadModule(name, loader); final Map> paths; try { paths = module.getPathsUnchecked(); } catch (ModuleLoadError e) { throw new IllegalArgumentException("Error loading module " + name + ": " + e.toString()); } final TreeMap> result = new TreeMap>(); for (Map.Entry> entry : paths.entrySet()) { final String path = entry.getKey(); final List loaders = entry.getValue(); if (loaders.isEmpty()) { result.put(path, Collections.emptyList()); } else if (loaders.size() == 1) { result.put(path, Collections.singletonList(loaders.get(0).toString())); } else { final ArrayList list = new ArrayList(); for (LocalLoader localLoader : loaders) { list.add(localLoader.toString()); } result.put(path, list); } } return result; } private Module loadModule(final String name, final ModuleLoader loader) { try { final Module module = loader.findLoadedModuleLocal(ModuleIdentifier.fromString(name)); if (module == null) { throw new IllegalArgumentException("Module " + name + " not found"); } return module; } catch (ModuleLoadError e) { throw new IllegalArgumentException("Error loading module " + name + ": " + e.toString()); } } private ModuleLoader getModuleLoader() { final ModuleLoader loader = reference.get(); if (loader == null) { throw new IllegalStateException("Module Loader is gone"); } return loader; } } private interface MBeanReg { boolean addMBean(ObjectName name, Object bean); void removeMBean(ObjectName name); void installReal(); } private static final class TempMBeanReg implements MBeanReg { private final Map mappings = new LinkedHashMap(); public boolean addMBean(final ObjectName name, final Object bean) { if (bean == null) { throw new IllegalArgumentException("bean is null"); } synchronized (ModuleLoader.class) { if (REG_REF == this) { return mappings.put(name, bean) == null; } else { return REG_REF.addMBean(name, bean); } } } public void removeMBean(final ObjectName name) { synchronized (ModuleLoader.class) { if (REG_REF == this) { mappings.remove(name); } else { REG_REF.removeMBean(name); } } } public void installReal() { synchronized (ModuleLoader.class) { RealMBeanReg real = new RealMBeanReg(); if (REG_REF == this) { REG_REF = real; for (Map.Entry entry : mappings.entrySet()) { real.addMBean(entry.getKey(), entry.getValue()); } mappings.clear(); } } } } private static final class RealMBeanReg implements MBeanReg { private final MBeanServer server; RealMBeanReg() { server = doPrivileged(new PrivilegedAction() { public MBeanServer run() { return ManagementFactory.getPlatformMBeanServer(); } }); } public boolean addMBean(final ObjectName name, final Object bean) { try { server.registerMBean(bean, name); return true; } catch (Throwable e) { } return false; } public void removeMBean(final ObjectName name) { try { server.unregisterMBean(name); } catch (Throwable e) { } } public void installReal() { // ignore } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleNotFoundException.java000066400000000000000000000050561257205723500310130ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; /** * Module not found exceptions are thrown when no module loaders can locate a module which fulfills a given module * identifier. * * @author John Bailey * @author David M. Lloyd */ public class ModuleNotFoundException extends ModuleLoadException { private static final long serialVersionUID = -1225396191255481860L; /** * Constructs a {@code ModuleNotFoundException} with no detail message. The cause is not initialized, and may * subsequently be initialized by a call to {@link #initCause(Throwable) initCause}. */ public ModuleNotFoundException() { } /** * Constructs a {@code ModuleNotFoundException} with the specified detail message. The cause is not initialized, and may * subsequently be initialized by a call to {@link #initCause(Throwable) initCause}. * * @param msg the detail message */ public ModuleNotFoundException(final String msg) { super(msg); } /** * Constructs a {@code ModuleNotFoundException} with the specified cause. The detail message is set to: *

(cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}). * * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) */ public ModuleNotFoundException(final Throwable cause) { super(cause); } /** * Constructs a {@code ModuleNotFoundException} with the specified detail message and cause. * * @param msg the detail message * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) */ public ModuleNotFoundException(final String msg, final Throwable cause) { super(msg, cause); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleSpec.java000066400000000000000000000234601257205723500262710ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.lang.instrument.ClassFileTransformer; import java.security.AllPermission; import java.security.PermissionCollection; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * A {@code Module} specification which is used by a {@code ModuleLoader} to define new modules. * * @apiviz.exclude * * @author David M. Lloyd */ public abstract class ModuleSpec { private final ModuleIdentifier moduleIdentifier; ModuleSpec(final ModuleIdentifier moduleIdentifier) { this.moduleIdentifier = moduleIdentifier; } /** * Get a builder for a new module specification. * * @param moduleIdentifier the module identifier * @return the builder */ public static Builder build(final ModuleIdentifier moduleIdentifier) { if (moduleIdentifier == null) { throw new IllegalArgumentException("moduleIdentifier is null"); } return new Builder() { private String mainClass; private AssertionSetting assertionSetting = AssertionSetting.INHERIT; private final List resourceLoaders = new ArrayList(0); private final List dependencies = new ArrayList(); private final Map properties = new LinkedHashMap(0); private LocalLoader fallbackLoader; private ModuleClassLoaderFactory moduleClassLoaderFactory; private ClassFileTransformer classFileTransformer; private PermissionCollection permissionCollection; @Override public Builder setFallbackLoader(final LocalLoader fallbackLoader) { this.fallbackLoader = fallbackLoader; return this; } @Override public Builder setMainClass(final String mainClass) { this.mainClass = mainClass; return this; } @Override public Builder setAssertionSetting(final AssertionSetting assertionSetting) { this.assertionSetting = assertionSetting == null ? AssertionSetting.INHERIT : assertionSetting; return this; } @Override public Builder addDependency(final DependencySpec dependencySpec) { dependencies.add(dependencySpec); return this; } @Override public Builder addResourceRoot(final ResourceLoaderSpec resourceLoader) { resourceLoaders.add(resourceLoader); return this; } @Override public Builder setModuleClassLoaderFactory(final ModuleClassLoaderFactory moduleClassLoaderFactory) { this.moduleClassLoaderFactory = moduleClassLoaderFactory; return this; } @Override public Builder setClassFileTransformer(final ClassFileTransformer classFileTransformer) { this.classFileTransformer = classFileTransformer; return this; } @Override public Builder addProperty(final String name, final String value) { properties.put(name, value); return this; } @Override public Builder setPermissionCollection(PermissionCollection permissionCollection) { this.permissionCollection = permissionCollection; return this; } @Override public ModuleSpec create() { return new ConcreteModuleSpec(moduleIdentifier, mainClass, assertionSetting, resourceLoaders.toArray(new ResourceLoaderSpec[resourceLoaders.size()]), dependencies.toArray(new DependencySpec[dependencies.size()]), fallbackLoader, moduleClassLoaderFactory, classFileTransformer, properties, permissionCollection); } @Override public ModuleIdentifier getIdentifier() { return moduleIdentifier; } }; } /** * Get a builder for a new module alias specification. * * @param moduleIdentifier the module identifier * @param aliasTarget the alias target identifier * @return the builder */ public static AliasBuilder buildAlias(final ModuleIdentifier moduleIdentifier, final ModuleIdentifier aliasTarget) { if (moduleIdentifier == null) { throw new IllegalArgumentException("moduleIdentifier is null"); } if (aliasTarget == null) { throw new IllegalArgumentException("aliasTarget is null"); } return new AliasBuilder() { public ModuleSpec create() { return new AliasModuleSpec(moduleIdentifier, aliasTarget); } public ModuleIdentifier getIdentifier() { return moduleIdentifier; } public ModuleIdentifier getAliasTarget() { return aliasTarget; } }; } /** * Get the module identifier for the module which is specified by this object. * * @return the module identifier */ public ModuleIdentifier getModuleIdentifier() { return moduleIdentifier; } /** * A builder for new concrete module specifications. * * @apiviz.exclude */ public interface Builder { /** * Set the main class for this module, or {@code null} for none. * * @param mainClass the main class name * @return this builder */ ModuleSpec.Builder setMainClass(String mainClass); /** * Set the default assertion setting for this module. * * @param assertionSetting the assertion setting * @return this builder */ ModuleSpec.Builder setAssertionSetting(AssertionSetting assertionSetting); /** * Add a dependency specification. * * @param dependencySpec the dependency specification * @return this builder */ ModuleSpec.Builder addDependency(DependencySpec dependencySpec); /** * Add a local resource root, from which this module will load class definitions and resources. * * @param resourceLoader the resource loader for the root * @return this builder */ ModuleSpec.Builder addResourceRoot(ResourceLoaderSpec resourceLoader); /** * Create the module specification from this builder. * * @return the module specification */ ModuleSpec create(); /** * Get the identifier of the module being defined by this builder. * * @return the module identifier */ ModuleIdentifier getIdentifier(); /** * Sets a "fall-back" loader that will attempt to load a class if all other mechanisms * are unsuccessful. * * @param fallbackLoader the fall-back loader * @return this builder */ ModuleSpec.Builder setFallbackLoader(final LocalLoader fallbackLoader); /** * Set the module class loader factory to use to create the module class loader for this module. * * @param moduleClassLoaderFactory the factory * @return this builder */ ModuleSpec.Builder setModuleClassLoaderFactory(ModuleClassLoaderFactory moduleClassLoaderFactory); /** * Set the class file transformer to use for this module. * * @param classFileTransformer the class file transformer * @return this builder */ ModuleSpec.Builder setClassFileTransformer(ClassFileTransformer classFileTransformer); /** * Add a property to this module specification. * * @param name the property name * @param value the property value * @return this builder */ ModuleSpec.Builder addProperty(String name, String value); /** * Set the permission collection for this module specification. If none is given, a collection implying * {@link AllPermission} is assumed. * * @param permissionCollection the permission collection * @return this builder */ ModuleSpec.Builder setPermissionCollection(PermissionCollection permissionCollection); } /** * A builder for new alias module specifications. */ public interface AliasBuilder { /** * Create the module specification from this builder. * * @return the module specification */ ModuleSpec create(); /** * Get the identifier of the module being defined by this builder. * * @return the module identifier */ ModuleIdentifier getIdentifier(); /** * Get the identifier of the module being referenced by this builder. * * @return the module identifier */ ModuleIdentifier getAliasTarget(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleXmlParser.java000077500000000000000000001371361257205723500273250ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.security.AccessControlContext; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.util.jar.JarFile; import org.jboss.modules.filter.MultiplePathFilterBuilder; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.security.FactoryPermissionCollection; import org.jboss.modules.security.ModularPermissionFactory; import org.jboss.modules.security.PermissionFactory; import org.jboss.modules.xml.MXParser; import org.jboss.modules.xml.XmlPullParser; import org.jboss.modules.xml.XmlPullParserException; import static org.jboss.modules.xml.XmlPullParser.CDSECT; import static org.jboss.modules.xml.XmlPullParser.COMMENT; import static org.jboss.modules.xml.XmlPullParser.DOCDECL; import static org.jboss.modules.xml.XmlPullParser.END_DOCUMENT; import static org.jboss.modules.xml.XmlPullParser.END_TAG; import static org.jboss.modules.xml.XmlPullParser.ENTITY_REF; import static org.jboss.modules.xml.XmlPullParser.FEATURE_PROCESS_NAMESPACES; import static org.jboss.modules.xml.XmlPullParser.IGNORABLE_WHITESPACE; import static org.jboss.modules.xml.XmlPullParser.PROCESSING_INSTRUCTION; import static org.jboss.modules.xml.XmlPullParser.START_DOCUMENT; import static org.jboss.modules.xml.XmlPullParser.START_TAG; import static org.jboss.modules.xml.XmlPullParser.TEXT; /** * A fast, validating module.xml parser. * * @author David M. Lloyd * @author thomas.diesler@jboss.com */ final class ModuleXmlParser { interface ResourceRootFactory { ResourceLoader createResourceLoader(final String rootPath, final String loaderPath, final String loaderName) throws IOException; } private ModuleXmlParser() { } private static final String MODULE_1_0 = "urn:jboss:module:1.0"; private static final String MODULE_1_1 = "urn:jboss:module:1.1"; private static final String MODULE_1_2 = "urn:jboss:module:1.2"; private static final String MODULE_1_3 = "urn:jboss:module:1.3"; private static final String E_MODULE = "module"; private static final String E_ARTIFACT = "artifact"; private static final String E_NATIVE_ARTIFACT = "native-artifact"; private static final String E_DEPENDENCIES = "dependencies"; private static final String E_RESOURCES = "resources"; private static final String E_MAIN_CLASS = "main-class"; private static final String E_RESOURCE_ROOT = "resource-root"; private static final String E_PATH = "path"; private static final String E_EXPORTS = "exports"; private static final String E_IMPORTS = "imports"; private static final String E_INCLUDE = "include"; private static final String E_EXCLUDE = "exclude"; private static final String E_INCLUDE_SET = "include-set"; private static final String E_EXCLUDE_SET = "exclude-set"; private static final String E_FILTER = "filter"; private static final String E_SYSTEM = "system"; private static final String E_PATHS = "paths"; private static final String E_MODULE_ALIAS = "module-alias"; private static final String E_MODULE_ABSENT = "module-absent"; private static final String E_PROPERTIES = "properties"; private static final String E_PROPERTY = "property"; private static final String E_PERMISSIONS = "permissions"; private static final String E_GRANT = "grant"; private static final String A_NAME = "name"; private static final String A_SLOT = "slot"; private static final String A_EXPORT = "export"; private static final String A_SERVICES = "services"; private static final String A_PATH = "path"; private static final String A_OPTIONAL = "optional"; private static final String A_TARGET_NAME = "target-name"; private static final String A_TARGET_SLOT = "target-slot"; private static final String A_VALUE = "value"; private static final String A_PERMISSION = "permission"; private static final String A_ACTIONS = "actions"; private static final String D_NONE = "none"; private static final String D_IMPORT = "import"; private static final String D_EXPORT = "export"; static ModuleSpec parseModuleXml(final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier, final File root, final File moduleInfoFile, final AccessControlContext context) throws ModuleLoadException, IOException { final FileInputStream fis; try { fis = new FileInputStream(moduleInfoFile); } catch (FileNotFoundException e) { throw new ModuleLoadException("No module.xml file found at " + moduleInfoFile); } try { return parseModuleXml(new ResourceRootFactory() { public ResourceLoader createResourceLoader(final String rootPath, final String loaderPath, final String loaderName) throws IOException { File file = new File(rootPath, loaderPath); if (file.isDirectory()) { return new FileResourceLoader(loaderName, file, context); } else { final JarFile jarFile = new JarFile(file, true); return new JarFileResourceLoader(loaderName, jarFile); } } }, root.getPath(), new BufferedInputStream(fis), moduleInfoFile.getPath(), moduleLoader, moduleIdentifier); } finally { StreamUtil.safeClose(fis); } } static ModuleSpec parseModuleXml(final ResourceRootFactory factory, final String rootPath, InputStream source, final String moduleInfoFile, final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier) throws ModuleLoadException, IOException { try { final MXParser parser = new MXParser(); parser.setFeature(FEATURE_PROCESS_NAMESPACES, true); parser.setInput(source, null); return parseDocument(factory, rootPath, parser, moduleLoader, moduleIdentifier); } catch (XmlPullParserException e) { throw new ModuleLoadException("Error loading module from " + moduleInfoFile, e); } finally { StreamUtil.safeClose(source); } } protected static XmlPullParserException unexpectedContent(final XmlPullParser reader) { final String kind; switch (reader.getEventType()) { case CDSECT: kind = "cdata"; break; case COMMENT: kind = "comment"; break; case DOCDECL: kind = "document decl"; break; case END_DOCUMENT: kind = "document end"; break; case END_TAG: kind = "element end"; break; case ENTITY_REF: kind = "entity ref"; break; case PROCESSING_INSTRUCTION: kind = "processing instruction"; break; case IGNORABLE_WHITESPACE: kind = "whitespace"; break; case START_DOCUMENT: kind = "document start"; break; case START_TAG: kind = "element start"; break; case TEXT: kind = "text"; break; default: kind = "unknown"; break; } final StringBuilder b = new StringBuilder("Unexpected content of type '").append(kind).append('\''); if (reader.getName() != null) { b.append(" named '").append(reader.getName()).append('\''); } if (reader.getText() != null) { b.append(", text is: '").append(reader.getText()).append('\''); } return new XmlPullParserException(b.toString(), reader, null); } protected static XmlPullParserException endOfDocument(final XmlPullParser reader) { return new XmlPullParserException("Unexpected end of document", reader, null); } private static XmlPullParserException invalidModuleName(final XmlPullParser reader, final ModuleIdentifier expected) { return new XmlPullParserException("Invalid/mismatched module name (expected " + expected + ")", reader, null); } private static XmlPullParserException missingAttributes(final XmlPullParser reader, final Set required) { final StringBuilder b = new StringBuilder("Missing one or more required attributes:"); for (String attribute : required) { b.append(' ').append(attribute); } return new XmlPullParserException(b.toString(), reader, null); } private static XmlPullParserException unknownAttribute(final XmlPullParser parser, final int index) { final String namespace = parser.getAttributeNamespace(index); final String prefix = parser.getAttributePrefix(index); final String name = parser.getAttributeName(index); final StringBuilder eb = new StringBuilder("Unknown attribute \""); if (prefix != null) eb.append(prefix).append(':'); eb.append(name); if (namespace != null) eb.append("\" from namespace \"").append(namespace); eb.append('"'); return new XmlPullParserException(eb.toString(), parser, null); } private static XmlPullParserException unknownAttributeValue(final XmlPullParser parser, final int index) { final String namespace = parser.getAttributeNamespace(index); final String prefix = parser.getAttributePrefix(index); final String name = parser.getAttributeName(index); final StringBuilder eb = new StringBuilder("Unknown value \""); eb.append(parser.getAttributeValue(index)); eb.append("\" for attribute \""); if (prefix != null && ! prefix.isEmpty()) eb.append(prefix).append(':'); eb.append(name); if (namespace != null && ! namespace.isEmpty()) eb.append("\" from namespace \"").append(namespace); eb.append('"'); return new XmlPullParserException(eb.toString(), parser, null); } private static void validateNamespace(final XmlPullParser reader) throws XmlPullParserException { switch (reader.getNamespace()) { case MODULE_1_0: case MODULE_1_1: case MODULE_1_2: case MODULE_1_3: break; default: throw unexpectedContent(reader); } } private static void assertNoAttributes(final XmlPullParser reader) throws XmlPullParserException { final int attributeCount = reader.getAttributeCount(); if (attributeCount > 0) { throw unknownAttribute(reader, 0); } } private static void validateAttributeNamespace(final XmlPullParser reader, final int index) throws XmlPullParserException { if (! reader.getAttributeNamespace(index).isEmpty()) { throw unknownAttribute(reader, index); } } private static ModuleSpec parseDocument(final ResourceRootFactory factory, final String rootPath, XmlPullParser reader, final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier) throws XmlPullParserException, IOException { int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case START_DOCUMENT: { return parseRootElement(factory, rootPath, reader, moduleLoader, moduleIdentifier); } case START_TAG: { final String element = reader.getName(); switch (element) { case E_MODULE: { final ModuleSpec.Builder specBuilder = ModuleSpec.build(moduleIdentifier); parseModuleContents(reader, factory, moduleLoader, moduleIdentifier, specBuilder, rootPath); parseEndDocument(reader); return specBuilder.create(); } case E_MODULE_ALIAS: { final ModuleSpec moduleSpec = parseModuleAliasContents(reader, moduleIdentifier); parseEndDocument(reader); return moduleSpec; } case E_MODULE_ABSENT: { parseModuleAbsentContents(reader, moduleIdentifier); return null; } default: { throw unexpectedContent(reader); } } } default: { throw unexpectedContent(reader); } } } } private static ModuleSpec parseRootElement(final ResourceRootFactory factory, final String rootPath, final XmlPullParser reader, final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier) throws XmlPullParserException, IOException { assertNoAttributes(reader); int eventType; while ((eventType = reader.nextTag()) != END_DOCUMENT) { switch (eventType) { case START_TAG: { validateNamespace(reader); final String element = reader.getName(); switch (element) { case E_MODULE: { final ModuleSpec.Builder specBuilder = ModuleSpec.build(moduleIdentifier); parseModuleContents(reader, factory, moduleLoader, moduleIdentifier, specBuilder, rootPath); parseEndDocument(reader); return specBuilder.create(); } case E_MODULE_ALIAS: { final ModuleSpec moduleSpec = parseModuleAliasContents(reader, moduleIdentifier); parseEndDocument(reader); return moduleSpec; } case E_MODULE_ABSENT: { parseModuleAbsentContents(reader, moduleIdentifier); return null; } default: { throw unexpectedContent(reader); } } } default: { throw unexpectedContent(reader); } } } throw endOfDocument(reader); } private static ModuleSpec parseModuleAliasContents(final XmlPullParser reader, final ModuleIdentifier moduleIdentifier) throws XmlPullParserException, IOException { final int count = reader.getAttributeCount(); String name = null; String slot = null; String targetName = null; String targetSlot = null; final Set required = new HashSet<>(Arrays.asList(A_NAME, A_TARGET_NAME)); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; case A_SLOT: slot = reader.getAttributeValue(i); break; case A_TARGET_NAME: targetName = reader.getAttributeValue(i); break; case A_TARGET_SLOT: targetSlot = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } if (! moduleIdentifier.equals(ModuleIdentifier.create(name, slot))) { throw invalidModuleName(reader, moduleIdentifier); } int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return ModuleSpec.buildAlias(moduleIdentifier, ModuleIdentifier.create(targetName, targetSlot)).create(); } default: { throw unexpectedContent(reader); } } } } private static void parseModuleAbsentContents(final XmlPullParser reader, final ModuleIdentifier moduleIdentifier) throws XmlPullParserException, IOException { final int count = reader.getAttributeCount(); String name = null; String slot = null; final Set required = new HashSet<>(Arrays.asList(A_NAME, A_SLOT)); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; case A_SLOT: slot = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } if (! moduleIdentifier.equals(ModuleIdentifier.create(name, slot))) { throw invalidModuleName(reader, moduleIdentifier); } int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return; } default: { throw unexpectedContent(reader); } } } } private static void parseModuleContents(final XmlPullParser reader, final ResourceRootFactory factory, final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier, final ModuleSpec.Builder specBuilder, final String rootPath) throws XmlPullParserException, IOException { final int count = reader.getAttributeCount(); String name = null; String slot = null; final Set required = new HashSet<>(Arrays.asList(A_NAME)); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; case A_SLOT: slot = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } if (! specBuilder.getIdentifier().equals(ModuleIdentifier.create(name, slot))) { throw invalidModuleName(reader, specBuilder.getIdentifier()); } // xsd:all MultiplePathFilterBuilder exportsBuilder = PathFilters.multiplePathFilterBuilder(true); ArrayList dependencies = new ArrayList<>(); Set visited = new HashSet<>(); int eventType; boolean gotPerms = false; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { specBuilder.addDependency(DependencySpec.createLocalDependencySpec(PathFilters.acceptAll(), exportsBuilder.create())); for (DependencySpec dependency : dependencies) { specBuilder.addDependency(dependency); } if (! gotPerms) specBuilder.setPermissionCollection(ModulesPolicy.DEFAULT_PERMISSION_COLLECTION); return; } case START_TAG: { validateNamespace(reader); final String element = reader.getName(); if (visited.contains(element)) { throw unexpectedContent(reader); } visited.add(element); switch (element) { case E_EXPORTS: parseFilterList(reader, exportsBuilder); break; case E_DEPENDENCIES: parseDependencies(reader, dependencies); break; case E_MAIN_CLASS: parseMainClass(reader, specBuilder); break; case E_RESOURCES: parseResources(factory, rootPath, reader, specBuilder); break; case E_PROPERTIES: parseProperties(reader, specBuilder); break; case E_PERMISSIONS: parsePermissions(reader, moduleLoader, moduleIdentifier, specBuilder); gotPerms = true; break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parseDependencies(final XmlPullParser reader, final ArrayList dependencies) throws XmlPullParserException, IOException { assertNoAttributes(reader); // xsd:choice int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_MODULE: parseModuleDependency(reader, dependencies); break; case E_SYSTEM: parseSystemDependency(reader, dependencies); break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parseModuleDependency(final XmlPullParser reader, final ArrayList dependencies) throws XmlPullParserException, IOException { String name = null; String slot = null; boolean export = false; boolean optional = false; String services = D_NONE; final Set required = new HashSet<>(Arrays.asList(A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; case A_SLOT: slot = reader.getAttributeValue(i); break; case A_EXPORT: export = Boolean.parseBoolean(reader.getAttributeValue(i)); break; case A_OPTIONAL: optional = Boolean.parseBoolean(reader.getAttributeValue(i)); break; case A_SERVICES: { services = reader.getAttributeValue(i); switch (services) { case D_NONE: case D_IMPORT: case D_EXPORT: break; default: throw unknownAttributeValue(reader, i); } break; } default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } final MultiplePathFilterBuilder importBuilder = PathFilters.multiplePathFilterBuilder(true); final MultiplePathFilterBuilder exportBuilder = PathFilters.multiplePathFilterBuilder(export); int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { assert services.equals(D_NONE) || services.equals(D_EXPORT) || services.equals(D_IMPORT); if (services.equals(D_EXPORT)) { // If services are to be re-exported, add META-INF/services -> true near the end of the list exportBuilder.addFilter(PathFilters.getMetaInfServicesFilter(), true); } if (export) { // If re-exported, add META-INF/** -> false at the end of the list (require explicit override) exportBuilder.addFilter(PathFilters.getMetaInfSubdirectoriesFilter(), false); exportBuilder.addFilter(PathFilters.getMetaInfFilter(), false); } final PathFilter exportFilter = exportBuilder.create(); final PathFilter importFilter; if (importBuilder.isEmpty()) { importFilter = services.equals(D_NONE) ? PathFilters.getDefaultImportFilter() : PathFilters.getDefaultImportFilterWithServices(); } else { if (! services.equals(D_NONE)) { importBuilder.addFilter(PathFilters.getMetaInfServicesFilter(), true); } importBuilder.addFilter(PathFilters.getMetaInfSubdirectoriesFilter(), false); importBuilder.addFilter(PathFilters.getMetaInfFilter(), false); importFilter = importBuilder.create(); } dependencies.add(DependencySpec.createModuleDependencySpec(importFilter, exportFilter, null, ModuleIdentifier.create(name, slot), optional)); return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_EXPORTS: parseFilterList(reader, exportBuilder); break; case E_IMPORTS: parseFilterList(reader, importBuilder); break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parseSystemDependency(final XmlPullParser reader, final ArrayList dependencies) throws XmlPullParserException, IOException { boolean export = false; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); switch (attribute) { case A_EXPORT: export = Boolean.parseBoolean(reader.getAttributeValue(i)); break; default: throw unexpectedContent(reader); } } Set paths = Collections.emptySet(); final MultiplePathFilterBuilder exportBuilder = PathFilters.multiplePathFilterBuilder(export); int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { final PathFilter exportFilter = exportBuilder.create(); dependencies.add(DependencySpec.createSystemDependencySpec(PathFilters.acceptAll(), exportFilter, paths)); return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_PATHS: { paths = parseSet(reader); break; } case E_EXPORTS: { parseFilterList(reader, exportBuilder); break; } default: { throw unexpectedContent(reader); } } } } } } private static void parseMainClass(final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { String name = null; final Set required = new HashSet<>(Arrays.asList(A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; default: throw unexpectedContent(reader); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } specBuilder.setMainClass(name); // consume remainder of element parseNoContent(reader); } private static void parseResources(final ResourceRootFactory factory, final String rootPath, final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { assertNoAttributes(reader); // xsd:choice int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { specBuilder.addResourceRoot(new ResourceLoaderSpec(new NativeLibraryResourceLoader(new File(rootPath, "lib")), PathFilters.rejectAll())); return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_RESOURCE_ROOT: { parseResourceRoot(factory, rootPath, reader, specBuilder); break; } case E_ARTIFACT: { parseArtifact(reader, specBuilder); break; } case E_NATIVE_ARTIFACT: { parseNativeArtifact(reader, specBuilder); break; } default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } static ResourceLoader createMavenArtifactLoader(final String name) throws IOException { File fp = MavenArtifactUtil.resolveJarArtifact(name); if (fp == null) return null; JarFile jarFile = new JarFile(fp, true); return new JarFileResourceLoader(name, jarFile); } static void createMavenNativeArtifactLoader(final String name, final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws IOException, XmlPullParserException { File fp = MavenArtifactUtil.resolveJarArtifact(name); if (fp == null) throw new XmlPullParserException(String.format("Failed to resolve native artifact '%s'", name), reader, null); File lib = new File(fp.getParentFile(), "lib"); if (!lib.exists()) { if (!fp.getParentFile().canWrite()) throw new XmlPullParserException(String.format("Native artifact '%s' cannot be unpacked", name), reader, null); StreamUtil.unzip(fp, fp.getParentFile()); } specBuilder.addResourceRoot(new ResourceLoaderSpec(new NativeLibraryResourceLoader(lib), PathFilters.rejectAll())); } private static void parseNativeArtifact(final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { String name = null; final Set required = new HashSet<>(Arrays.asList(A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { try { createMavenNativeArtifactLoader(name, reader, specBuilder); } catch (IOException e) { throw new XmlPullParserException(String.format("Failed to add artifact '%s'", name), reader, e); } return; } case START_TAG: { throw unexpectedContent(reader); } default: { throw unexpectedContent(reader); } } } } private static void parseArtifact(final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { String name = null; final Set required = new HashSet<>(Arrays.asList(A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } ResourceLoader resourceLoader; int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { try { resourceLoader = createMavenArtifactLoader(name); } catch (IOException e) { throw new XmlPullParserException(String.format("Failed to add artifact '%s'", name), reader, e); } if (resourceLoader == null) throw new XmlPullParserException(String.format("Failed to resolve artifact '%s'", name), reader, null); specBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader)); return; } case START_TAG: { throw unexpectedContent(reader); } default: { throw unexpectedContent(reader); } } } } private static void parseResourceRoot(final ResourceRootFactory factory, final String rootPath, final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { String name = null; String path = null; final Set required = new HashSet<>(Arrays.asList(A_PATH)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; case A_PATH: path = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } if (name == null) name = path; final MultiplePathFilterBuilder filterBuilder = PathFilters.multiplePathFilterBuilder(true); final ResourceLoader resourceLoader; final Set encountered = new HashSet<>(); int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { try { resourceLoader = factory.createResourceLoader(rootPath, path, name); } catch (IOException e) { throw new XmlPullParserException(String.format("Failed to add resource root '%s' at path '%s'", name, path), reader, e); } specBuilder.addResourceRoot(new ResourceLoaderSpec(resourceLoader, filterBuilder.create())); return; } case START_TAG: { validateNamespace(reader); final String element = reader.getName(); if (! encountered.add(element)) throw unexpectedContent(reader); switch (element) { case E_FILTER: parseFilterList(reader, filterBuilder); break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parseFilterList(final XmlPullParser reader, final MultiplePathFilterBuilder builder) throws XmlPullParserException, IOException { assertNoAttributes(reader); // xsd:choice int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_INCLUDE: parsePath(reader, true, builder); break; case E_EXCLUDE: parsePath(reader, false, builder); break; case E_INCLUDE_SET: parseSet(reader, true, builder); break; case E_EXCLUDE_SET: parseSet(reader, false, builder); break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parsePath(final XmlPullParser reader, final boolean include, final MultiplePathFilterBuilder builder) throws XmlPullParserException, IOException { String path = null; final Set required = new HashSet<>(Arrays.asList(A_PATH)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_PATH: path = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } final boolean literal = path.indexOf('*') == -1 && path.indexOf('?') == -1; if (literal) { if (path.charAt(path.length() - 1) == '/') { builder.addFilter(PathFilters.isChildOf(path), include); } else { builder.addFilter(PathFilters.is(path), include); } } else { builder.addFilter(PathFilters.match(path), include); } // consume remainder of element parseNoContent(reader); } private static Set parseSet(final XmlPullParser reader) throws XmlPullParserException, IOException { assertNoAttributes(reader); final Set set = new FastCopyHashSet<>(); // xsd:choice int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return set; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_PATH: parsePathName(reader, set); break; default: throw unexpectedContent(reader); } } } } } private static void parseSet(final XmlPullParser reader, final boolean include, final MultiplePathFilterBuilder builder) throws XmlPullParserException, IOException { builder.addFilter(PathFilters.in(parseSet(reader)), include); } private static void parsePathName(final XmlPullParser reader, final Set set) throws XmlPullParserException, IOException { String name = null; final Set required = new HashSet<>(Arrays.asList(A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } set.add(name); // consume remainder of element parseNoContent(reader); } private static void parseProperties(final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { assertNoAttributes(reader); // xsd:choice int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_PROPERTY: { parseProperty(reader, specBuilder); break; } default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parseProperty(final XmlPullParser reader, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { String name = null; String value = null; final Set required = new HashSet<>(Arrays.asList(A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_NAME: name = reader.getAttributeValue(i); break; case A_VALUE: value = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } specBuilder.addProperty(name, value == null ? "true" : value); if ("jboss.assertions".equals(name)) try { specBuilder.setAssertionSetting(AssertionSetting.valueOf(value.toUpperCase(Locale.US))); } catch (IllegalArgumentException ignored) {} // consume remainder of element parseNoContent(reader); } private static void parsePermissions(final XmlPullParser reader, final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier, final ModuleSpec.Builder specBuilder) throws XmlPullParserException, IOException { assertNoAttributes(reader); // xsd:choice ArrayList list = new ArrayList<>(); int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { specBuilder.setPermissionCollection(new FactoryPermissionCollection(list.toArray(new PermissionFactory[list.size()]))); return; } case START_TAG: { validateNamespace(reader); switch (reader.getName()) { case E_GRANT: { parseGrant(reader, moduleLoader, moduleIdentifier, list); break; } default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } } private static void parseGrant(final XmlPullParser reader, final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier, final ArrayList list) throws XmlPullParserException, IOException { String permission = null; String name = null; String actions = null; final Set required = new HashSet<>(Arrays.asList(A_PERMISSION, A_NAME)); final int count = reader.getAttributeCount(); for (int i = 0; i < count; i ++) { validateAttributeNamespace(reader, i); final String attribute = reader.getAttributeName(i); required.remove(attribute); switch (attribute) { case A_PERMISSION: permission = reader.getAttributeValue(i); break; case A_NAME: name = reader.getAttributeValue(i); break; case A_ACTIONS: actions = reader.getAttributeValue(i); break; default: throw unknownAttribute(reader, i); } } if (! required.isEmpty()) { throw missingAttributes(reader, required); } list.add(new ModularPermissionFactory(moduleLoader, moduleIdentifier, permission, name, actions)); // consume remainder of element parseNoContent(reader); } private static void parseNoContent(final XmlPullParser reader) throws XmlPullParserException, IOException { int eventType; for (;;) { eventType = reader.nextTag(); switch (eventType) { case END_TAG: { return; } default: { throw unexpectedContent(reader); } } } } static void parseEndDocument(final XmlPullParser reader) throws XmlPullParserException, IOException { int eventType; for (;;) { eventType = reader.nextToken(); switch (eventType) { case END_DOCUMENT: { return; } case TEXT: case CDSECT: { if (! reader.isWhitespace()) { throw unexpectedContent(reader); } // ignore break; } case IGNORABLE_WHITESPACE: case COMMENT: { // ignore break; } default: { throw unexpectedContent(reader); } } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModuleXmlUtil.java000066400000000000000000000136361257205723500270010ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; /** * Utility class for default module file names. *

* Date: 10.05.2011 * * @author James R. Perkins */ class ModuleXmlUtil { public static final String DEFAULT_FILENAME = "module.xml"; /** * Private constructor. */ private ModuleXmlUtil() { } /** * Creates a file based on the directory and the module identifier. *

* The {@code dir} parameter must be a directory and the {@code identifier} cannot be {@code null}. * * @param dir the base directory where the file should be located. * @param identifier the module identifier. * * @return the module XML file. * @throws IllegalArgumentException if the {@code dir} parameter is not a directory or an argument is {@code null}. */ public static File toFile(final File dir, final ModuleIdentifier identifier) { return toFile(dir, DEFAULT_FILENAME, identifier); } /** * Creates a file based on the directory and the module identifier. *

* The {@code dir} parameter must be a directory and the {@code identifier} cannot be {@code null}. * * @param dir the base directory where the file should be located. * @param name the name of the XML file. * @param identifier the module identifier. * * @return the module XML file. * @throws IllegalArgumentException if the {@code dir} parameter is not a directory or an argument is {@code null}. */ public static File toFile(final File dir, final String name, final ModuleIdentifier identifier) { if (dir == null || !dir.isDirectory()) { throw new IllegalArgumentException(String.format("Must be a directory. File %s is not a directory.", dir)); } if (name == null || name.isEmpty()) { throw new IllegalArgumentException("The name cannot be empty."); } if (identifier == null) { throw new IllegalArgumentException("The module identifier cannot be null."); } return new File(dir, baseFilename(name, identifier)); } /** * Creates a path name from the module identifier. The name always ends with the separator character. *

* A {@code null} identifier will result in no separator being used. * * @param identifier the module identifier. * @param separator the directory separator. * * @return a path name of the module identifier. * @throws IllegalArgumentException if the module identifier is {@code null}. */ public static String baseDirectory(final ModuleIdentifier identifier, final String separator) { if (identifier == null) { throw new IllegalArgumentException("The module identifier cannot be null."); } final String namePath = identifier.getName().replace('.', File.separatorChar); final StringBuilder baseName = new StringBuilder(); baseName.append(namePath). append((separator == null ? "" : separator)). append(identifier.getSlot()). append((separator == null ? "" : separator)); return baseName.toString(); } /** * Creates a path name from the module identifier with the default {@link java.io.File#separator} character. * * @param identifier the module identifier. * * @return a path name of the module identifier. * @throws IllegalArgumentException if the module identifier is {@code null}. * @see #baseDirectory(ModuleIdentifier, String) */ public static String baseDirectory(final ModuleIdentifier identifier) { return baseDirectory(identifier, File.separator); } /** * Creates a path name to the module XML file from the module identifier. Uses the {@link #DEFAULT_FILENAME} for * the XML file name. * * @param identifier the module identifier. * * @return a path name to the module XML file. * @throws IllegalArgumentException if the module identifier is {@code null}. */ public static String baseFilename(final ModuleIdentifier identifier) { return baseFilename(DEFAULT_FILENAME, identifier); } /** * Creates a path name to the module XML file from the module identifier. * * @param name the XML file name. * @param identifier the module identifier. * * @return a path name to the module XML file. * @throws IllegalArgumentException if the module identifier is {@code null}. */ public static String baseFilename(final String name, final ModuleIdentifier identifier) { return baseDirectory(identifier) + name; } /** * Creates a path name to the module XML * * @param name the XML file name. file from the module identifier. * @param separator the directory separator. * @param identifier the module identifier. * * @return a path name to the module XML file. * @throws IllegalArgumentException if the module identifier is {@code null}. */ public static String baseFilename(final String name, final String separator, final ModuleIdentifier identifier) { return baseDirectory(identifier, separator) + name; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModulesPolicy.java000066400000000000000000000051521257205723500270170ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.AllPermission; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; import java.security.ProtectionDomain; import java.security.Provider; final class ModulesPolicy extends Policy { private static final AllPermission ALL_PERMISSION = new AllPermission(); static final Permissions DEFAULT_PERMISSION_COLLECTION = getAllPermission(); private static final CodeSource ourCodeSource = ModulesPolicy.class.getProtectionDomain().getCodeSource(); private final Policy policy; private static Permissions getAllPermission() { final Permissions permissions = new Permissions(); permissions.add(ALL_PERMISSION); return permissions; } public ModulesPolicy(final Policy policy) { this.policy = policy; } public Provider getProvider() { return policy.getProvider(); } public String getType() { return policy.getType(); } public Parameters getParameters() { return policy.getParameters(); } public PermissionCollection getPermissions(final CodeSource codesource) { return codesource.equals(ourCodeSource) ? getAllPermission() : policy.getPermissions(codesource); } public PermissionCollection getPermissions(final ProtectionDomain domain) { final CodeSource codeSource = domain.getCodeSource(); return codeSource != null && codeSource.equals(ourCodeSource) ? getAllPermission() : policy.getPermissions(domain); } public boolean implies(final ProtectionDomain domain, final Permission permission) { final CodeSource codeSource = domain.getCodeSource(); return codeSource != null && codeSource.equals(ourCodeSource) || policy.implies(domain, permission); } public void refresh() { policy.refresh(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/NativeLibraryResourceLoader.java000066400000000000000000000367331257205723500316520ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Locale; /** * A base class for resource loaders which can load native libraries. * * @author David M. Lloyd */ public class NativeLibraryResourceLoader extends AbstractResourceLoader { /** * Separate class for native platform ID which is only loaded when native libs are loaded. */ static class Identification { static final String OS_ID; static final String CPU_ID; static final String ARCH_NAME; static final String[] NATIVE_SEARCH_PATHS; static { final Object[] strings = AccessController.doPrivileged(new PrivilegedAction() { public Object[] run() { // First, identify the operating system. boolean knownOs = true; String osName; // let the user override it. osName = System.getProperty("jboss.modules.os-name"); if (osName == null) { String sysOs = System.getProperty("os.name"); if (sysOs == null) { osName = "unknown"; knownOs = false; } else { sysOs = sysOs.toUpperCase(Locale.US); if (sysOs.startsWith("LINUX")) { osName = "linux"; } else if (sysOs.startsWith("MAC OS")) { osName = "macosx"; } else if (sysOs.startsWith("WINDOWS")) { osName = "win"; } else if (sysOs.startsWith("OS/2")) { osName = "os2"; } else if (sysOs.startsWith("SOLARIS") || sysOs.startsWith("SUNOS")) { osName = "solaris"; } else if (sysOs.startsWith("MPE/IX")) { osName = "mpeix"; } else if (sysOs.startsWith("HP-UX")) { osName = "hpux"; } else if (sysOs.startsWith("AIX")) { osName = "aix"; } else if (sysOs.startsWith("OS/390")) { osName = "os390"; } else if (sysOs.startsWith("OS/400")) { osName = "os400"; } else if (sysOs.startsWith("FREEBSD")) { osName = "freebsd"; } else if (sysOs.startsWith("OPENBSD")) { osName = "openbsd"; } else if (sysOs.startsWith("NETBSD")) { osName = "netbsd"; } else if (sysOs.startsWith("IRIX")) { osName = "irix"; } else if (sysOs.startsWith("DIGITAL UNIX")) { osName = "digitalunix"; } else if (sysOs.startsWith("OSF1")) { osName = "osf1"; } else if (sysOs.startsWith("OPENVMS")) { osName = "openvms"; } else if (sysOs.startsWith("IOS")) { osName = "iOS"; } else { osName = "unknown"; knownOs = false; } } } // Next, our CPU ID and its compatible variants. boolean knownCpu = true; ArrayList cpuNames = new ArrayList<>(); String cpuName = System.getProperty("jboss.modules.cpu-name"); if (cpuName == null) { String sysArch = System.getProperty("os.arch"); if (sysArch == null) { cpuName = "unknown"; knownCpu = false; } else { boolean hasEndian = false; boolean hasHardFloatABI = false; sysArch = sysArch.toUpperCase(Locale.US); if (sysArch.startsWith("SPARCV9") || sysArch.startsWith("SPARC64")) { cpuName = "sparcv9"; } else if (sysArch.startsWith("SPARC")) { cpuName = "sparc"; } else if (sysArch.startsWith("X86_64") || sysArch.startsWith("AMD64")) { cpuName = "x86_64"; } else if (sysArch.startsWith("I386")) { cpuName = "i386"; } else if (sysArch.startsWith("I486")) { cpuName = "i486"; } else if (sysArch.startsWith("I586")) { cpuName = "i586"; } else if (sysArch.startsWith("I686") || sysArch.startsWith("X86") || sysArch.contains("IA32")) { cpuName = "i686"; } else if (sysArch.startsWith("X32")) { cpuName = "x32"; } else if (sysArch.startsWith("PPC64")) { cpuName = "ppc64"; } else if (sysArch.startsWith("PPC") || sysArch.startsWith("POWER")) { cpuName = "ppc"; } else if (sysArch.startsWith("ARMV7A") || sysArch.contains("AARCH32")) { hasEndian = true; hasHardFloatABI = true; cpuName = "armv7a"; } else if (sysArch.startsWith("AARCH64") || sysArch.startsWith("ARM64") || sysArch.startsWith("ARMV8") || sysArch.startsWith("PXA9") || sysArch.startsWith("PXA10")) { hasEndian = true; cpuName = "aarch64"; } else if (sysArch.startsWith("PXA27")) { hasEndian = true; cpuName = "armv5t-iwmmx"; } else if (sysArch.startsWith("PXA3")) { hasEndian = true; cpuName = "armv5t-iwmmx2"; } else if (sysArch.startsWith("ARMV4T") || sysArch.startsWith("EP93")) { hasEndian = true; cpuName = "armv4t"; } else if (sysArch.startsWith("ARMV4") || sysArch.startsWith("EP73")) { hasEndian = true; cpuName = "armv4"; } else if (sysArch.startsWith("ARMV5T") || sysArch.startsWith("PXA") || sysArch.startsWith("IXC") || sysArch.startsWith("IOP") || sysArch.startsWith("IXP") || sysArch.startsWith("CE")) { hasEndian = true; String isaList = System.getProperty("sun.arch.isalist"); if (isaList != null) { if (isaList.toUpperCase(Locale.US).contains("MMX2")) { cpuName = "armv5t-iwmmx2"; } else if (isaList.toUpperCase(Locale.US).contains("MMX")) { cpuName = "armv5t-iwmmx"; } else { cpuName = "armv5t"; } } else { cpuName = "armv5t"; } } else if (sysArch.startsWith("ARMV5")) { hasEndian = true; cpuName = "armv5"; } else if (sysArch.startsWith("ARMV6")) { hasEndian = true; hasHardFloatABI = true; cpuName = "armv6"; } else if (sysArch.startsWith("PA_RISC2.0W")) { cpuName = "parisc64"; } else if (sysArch.startsWith("PA_RISC") || sysArch.startsWith("PA-RISC")) { cpuName = "parisc"; } else if (sysArch.startsWith("IA64")) { // HP-UX reports IA64W for 64-bit Itanium and IA64N when running // in 32-bit mode. cpuName = sysArch.toLowerCase(Locale.US); } else if (sysArch.startsWith("ALPHA")) { cpuName = "alpha"; } else if (sysArch.startsWith("MIPS")) { cpuName = "mips"; } else { knownCpu = false; cpuName = "unknown"; } boolean be = false; boolean hf = false; if (knownCpu && hasEndian && "big".equals(System.getProperty("sun.cpu.endian", "little"))) { be = true; } if (knownCpu && hasHardFloatABI) { String archAbi = System.getProperty("sun.arch.abi"); if (archAbi != null) { if (archAbi.toUpperCase(Locale.US).contains("HF")) { hf = true; } } else { String libPath = System.getProperty("java.library.path"); if (libPath != null && libPath.toUpperCase(Locale.US).contains("GNUEABIHF")) { hf = true; } } if (hf) cpuName += "-hf"; } if (knownCpu) { switch (cpuName) { case "i686": cpuNames.add("i686"); case "i586": cpuNames.add("i586"); case "i486": cpuNames.add("i486"); case "i386": cpuNames.add("i386"); break; case "armv7a": cpuNames.add("armv7a"); if (hf) break; case "armv6": cpuNames.add("armv6"); if (hf) break; case "armv5t": cpuNames.add("armv5t"); case "armv5": cpuNames.add("armv5"); case "armv4t": cpuNames.add("armv4t"); case "armv4": cpuNames.add("armv4"); break; case "armv5t-iwmmx2": cpuNames.add("armv5t-iwmmx2"); case "armv5t-iwmmx": cpuNames.add("armv5t-iwmmx"); cpuNames.add("armv5t"); cpuNames.add("armv5"); cpuNames.add("armv4t"); cpuNames.add("armv4"); break; default: cpuNames.add(cpuName); break; } if (hf || be) for (int i = 0; i < cpuNames.size(); i++) { String name = cpuNames.get(i); if (be) name += "-be"; if (hf) name += "-hf"; cpuNames.set(i, name); } cpuName = cpuNames.get(0); } } } // Finally, search paths. final int cpuCount = cpuNames.size(); String[] searchPaths = new String[cpuCount]; if (knownOs && knownCpu) { for (int i = 0; i < cpuCount; i++) { final String name = cpuNames.get(i); searchPaths[i] = osName + "-" + name; } } else { searchPaths = new String[0]; } return new Object[] { osName, cpuName, osName + "-" + cpuName, searchPaths }; } }); OS_ID = strings[0].toString(); CPU_ID = strings[1].toString(); ARCH_NAME = strings[2].toString(); NATIVE_SEARCH_PATHS = (String[]) strings[3]; } } /** * The filesystem root of the resource loader. */ private final File root; /** * Construct a new instance. * * @param root the filesystem root of the resource loader */ public NativeLibraryResourceLoader(final File root) { this.root = root; } /** {@inheritDoc} */ public String getLibrary(final String name) { final String mappedName = System.mapLibraryName(name); final File root = this.root; File testFile; for (String path : Identification.NATIVE_SEARCH_PATHS) { testFile = new File(new File(root, path), mappedName); if (testFile.exists()) { return testFile.getAbsolutePath(); } } return null; } /** * Get the filesystem root of the resource loader. * * @return the filesystem root of the resource loader */ public File getRoot() { return root; } /** * Get the detected architecture name for this platform. * * @return the architecture name */ public static String getArchName() { return Identification.ARCH_NAME; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/PackageSpec.java000066400000000000000000000124361257205723500264000ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.net.URL; /** * A specification for a package to define. * * @apiviz.exclude * @author David M. Lloyd */ public final class PackageSpec { private String specTitle; private String specVersion; private String specVendor; private String implTitle; private String implVersion; private String implVendor; private URL sealBase; private AssertionSetting assertionSetting = AssertionSetting.INHERIT; /** * Get the package specification title. * * @return the specification title * @see java.util.jar.Attributes.Name#SPECIFICATION_TITLE */ public String getSpecTitle() { return specTitle; } /** * Set the package specification title. * * @param specTitle the specification title * @see java.util.jar.Attributes.Name#SPECIFICATION_TITLE */ public void setSpecTitle(final String specTitle) { this.specTitle = specTitle; } /** * Get the package specification version. * * @return the specification version * @see java.util.jar.Attributes.Name#SPECIFICATION_VERSION */ public String getSpecVersion() { return specVersion; } /** * Set the package specification version. * * @param specVersion the specification version * @see java.util.jar.Attributes.Name#SPECIFICATION_VERSION */ public void setSpecVersion(final String specVersion) { this.specVersion = specVersion; } /** * Set the package specification vendor. * * @return the specification vendor * @see java.util.jar.Attributes.Name#SPECIFICATION_VENDOR */ public String getSpecVendor() { return specVendor; } /** * Set the package specification vendor. * * @param specVendor the specification vendor * @see java.util.jar.Attributes.Name#SPECIFICATION_VENDOR */ public void setSpecVendor(final String specVendor) { this.specVendor = specVendor; } /** * Get the implementation title. * * @return the implementation title * @see java.util.jar.Attributes.Name#IMPLEMENTATION_TITLE */ public String getImplTitle() { return implTitle; } /** * Set the implementation title. * * @param implTitle the implementation title * @see java.util.jar.Attributes.Name#IMPLEMENTATION_TITLE */ public void setImplTitle(final String implTitle) { this.implTitle = implTitle; } /** * Get the implementation version. * * @return the implementation version * @see java.util.jar.Attributes.Name#IMPLEMENTATION_VERSION */ public String getImplVersion() { return implVersion; } /** * Set the implementation version. * * @param implVersion the implementation version * @see java.util.jar.Attributes.Name#IMPLEMENTATION_VENDOR */ public void setImplVersion(final String implVersion) { this.implVersion = implVersion; } /** * Get the implementation vendor. * * @return the implementation vendor * @see java.util.jar.Attributes.Name#IMPLEMENTATION_VENDOR */ public String getImplVendor() { return implVendor; } /** * Set the implementation vendor. * * @param implVendor the implementation vendor * @see java.util.jar.Attributes.Name#IMPLEMENTATION_VENDOR */ public void setImplVendor(final String implVendor) { this.implVendor = implVendor; } /** * Get the URL against which this package is sealed. * * @return the seal base URL * @see java.util.jar.Attributes.Name#SEALED */ public URL getSealBase() { return sealBase; } /** * Set the URL against which this package is sealed. * * @param sealBase the seal base URL * @see java.util.jar.Attributes.Name#SEALED */ public void setSealBase(URL sealBase) { this.sealBase = sealBase; } /** * Get the package assertion setting. * * @return the package assertion setting */ public AssertionSetting getAssertionSetting() { return assertionSetting; } /** * Set the package assertion setting. * * @param assertionSetting the package assertion setting */ public void setAssertionSetting(final AssertionSetting assertionSetting) { if (assertionSetting == null) { throw new IllegalArgumentException("assertionSetting is null"); } this.assertionSetting = assertionSetting; } }jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/PathUtils.java000066400000000000000000000231401257205723500261410ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.jboss.modules.filter.PathFilter; /** * General helpful path utility methods. * * @author David M. Lloyd */ public final class PathUtils { private PathUtils() { } /** * Filter the paths from {@code source} into {@code target} using {@code filter}. * * @param source the source paths * @param filter the filter to apply * @param target the destination for filtered paths * @param the collection type * @return the {@code target} set */ public static > T filterPaths(Iterable source, PathFilter filter, T target) { for (String path : source) { if (filter.accept(path)) { target.add(path); } } return target; } /** * Attempt to get a set of all paths defined directly by the given class loader. If the path set cannot be * ascertained, {@code null} is returned. * * @param classLoader the class loader to inspect * @return the set, or {@code null} if the paths could not be determined */ public static Set getPathSet(ClassLoader classLoader) { if (classLoader == null) { return JDKPaths.JDK; } else if (classLoader instanceof ModuleClassLoader) { final ModuleClassLoader moduleClassLoader = (ModuleClassLoader) classLoader; return Collections.unmodifiableSet(moduleClassLoader.getPaths()); } else if (classLoader instanceof URLClassLoader) { // here's where it starts to get ugly... final URLClassLoader urlClassLoader = (URLClassLoader) classLoader; final URL[] urls = urlClassLoader.getURLs(); final Set paths = new HashSet(); for (URL url : urls) { final URI uri; try { uri = url.toURI(); } catch (URISyntaxException e) { return null; } final String scheme = uri.getScheme(); if ("file".equals(scheme)) { final File file; try { file = new File(uri); } catch (Exception e) { return null; } if (file.exists()) { if (file.isDirectory()) { JDKPaths.processDirectory0(paths, file); } else { try { JDKPaths.processJar(paths, file); } catch (IOException e) { return null; } } } } } return Collections.unmodifiableSet(paths); } else { // ??? return null; } } /** * Relativize the given path. Removes any leading {@code /} segments from the path. * * @param path the path to relativize * @return the relative path */ public static String relativize(String path) { for (int i = 0; i < path.length(); i ++) { if (path.charAt(i) != '/' && path.charAt(i) != File.separatorChar) { return i == 0 ? path : path.substring(i); } } return ""; } /** * Canonicalize the given path. Removes all {@code .} and {@code ..} segments from the path. * * @param path the relative or absolute possibly non-canonical path * @return the canonical path */ public static String canonicalize(String path) { final int length = path.length(); // 0 - start // 1 - got one . // 2 - got two . // 3 - got / int state = 0; if (length == 0) { return path; } final char[] targetBuf = new char[length]; // string segment end exclusive int e = length; // string cursor position int i = length; // buffer cursor position int a = length - 1; // number of segments to skip int skip = 0; loop: while (--i >= 0) { char c = path.charAt(i); outer: switch (c) { case '/': { inner: switch (state) { case 0: state = 3; e = i; break outer; case 1: state = 3; e = i; break outer; case 2: state = 3; e = i; skip ++; break outer; case 3: e = i; break outer; default: throw new IllegalStateException(); } // not reached! } case '.': { inner: switch (state) { case 0: state = 1; break outer; case 1: state = 2; break outer; case 2: break inner; // emit! case 3: state = 1; break outer; default: throw new IllegalStateException(); } // fall thru } default: { if (File.separatorChar != '/' && c == File.separatorChar) { switch (state) { case 0: state = 3; e = i; break outer; case 1: state = 3; e = i; break outer; case 2: state = 3; e = i; skip ++; break outer; case 3: e = i; break outer; default: throw new IllegalStateException(); } // not reached! } final int newE = e > 0 ? path.lastIndexOf('/', e - 1) : -1; final int segmentLength = e - newE - 1; if (skip > 0) { skip--; } else { if (state == 3) { targetBuf[a--] = '/'; } path.getChars(newE + 1, e, targetBuf, (a -= segmentLength) + 1); } state = 0; i = newE + 1; e = newE; break; } } } if (state == 3) { targetBuf[a--] = '/'; } return new String(targetBuf, a + 1, length - a - 1); } /** * Determine whether one path is a child of another. * * @param parent the parent path * @param child the child path * @return {@code true} if the child is truly a child of parent */ public static boolean isChild(final String parent, final String child) { String cp = canonicalize(parent); String cc = canonicalize(child); if (isRelative(cp) != isRelative(cc)) { throw new IllegalArgumentException("Cannot compare relative and absolute paths"); } final int cpl = cp.length(); return cpl == 0 || cc.length() > cpl + 1 && cc.startsWith(cp) && cc.charAt(cpl) == '/'; } /** * Determine whether one path is a direct (or immediate) child of another. * * @param parent the parent path * @param child the child path * @return {@code true} if the child is truly a direct child of parent */ public static boolean isDirectChild(final String parent, final String child) { String cp = canonicalize(parent); String cc = canonicalize(child); if (isRelative(cp) != isRelative(cc)) { throw new IllegalArgumentException("Cannot compare relative and absolute paths"); } final int cpl = cp.length(); if (cpl == 0) { return cc.indexOf('/') < 0; } else { return cc.length() > cpl + 1 && cc.startsWith(cp) && cc.charAt(cpl) == '/' && cc.indexOf('/', cpl + 1) == -1; } } /** * Determine whether a path name is relative. * * @param path the path name * @return {@code true} if it is relative */ public static boolean isRelative(final String path) { return path.isEmpty() || !isSeparator(path.charAt(0)); } /** * Determine whether the given character is a {@code /} or a platform-specific separator. * * @param ch the character to test * @return {@code true} if it is a separator */ public static boolean isSeparator(final char ch) { // the second half of this compare will optimize away on / OSes return ch == '/' || File.separatorChar != '/' && ch == File.separatorChar; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Paths.java000066400000000000000000000032461257205723500253100ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.List; import java.util.Map; /** * A pair of path maps. * * @param the type of object that each path refers to * @param the type of the source object used to calculate the path maps * * @author David M. Lloyd */ final class Paths { private final A[] sourceList; private final Map> allPaths; Paths(final A[] sourceList, final Map> allPaths) { this.sourceList = sourceList; this.allPaths = allPaths; } Map> getAllPaths() { return allPaths; } A[] getSourceList(A[] defVal) { final A[] sourceList = this.sourceList; return sourceList == null ? defVal : sourceList; } static final Paths NONE = new Paths(null, null); @SuppressWarnings({ "unchecked" }) static Paths none() { return (Paths) NONE; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/PropertyReadAction.java000066400000000000000000000023561257205723500300100ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.PrivilegedAction; /** * @author David M. Lloyd */ class PropertyReadAction implements PrivilegedAction { private final String key; private final String defVal; PropertyReadAction(final String key) { this(key, null); } PropertyReadAction(final String key, final String defVal) { this.key = key; this.defVal = defVal; } public String run() { return System.getProperty(key, defVal); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/PropertyWriteAction.java000066400000000000000000000023061257205723500302220ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.PrivilegedAction; /** * Date: 11.05.2011 * * @author James R. Perkins */ class PropertyWriteAction implements PrivilegedAction { private final String key; private final String value; PropertyWriteAction(final String key, final String value) { this.key = key; this.value = value; } @Override public String run() { return System.setProperty(key, value); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Resource.java000066400000000000000000000027741257205723500260250ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.InputStream; import java.net.URL; /** * A single resource from a {@link ResourceLoader}. * * @author David M. Lloyd */ public interface Resource { /** * Get the relative resource name. * * @return the name */ String getName(); /** * Get the complete URL of this resource. * * @return the URL */ URL getURL(); /** * Open an input stream to this resource. * * @return the stream * @throws java.io.IOException if an I/O error occurs */ InputStream openStream() throws IOException; /** * Get the size of the resource, if known. * * @return the size, or 0L if unknown */ long getSize(); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ResourceLoader.java000066400000000000000000000063011257205723500271420ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.util.Collection; /** * A loader for resources from a specific resource root within a module. * * @author David M. Lloyd */ public interface ResourceLoader { /** * Get the name of the root represented by this resource loader. * * @return the name of the root */ String getRootName(); /** * Get the class specification for the given class name. If no matching class is found, {@code null} is returned. * * @param fileName the fileName of the class, e.g. for the class org.jboss.modules.ResourceLoader * the fileName will be org/jboss/modules/ResourceLoader.class * @return the class specification, or {@code null} if the named class is not found * @throws IOException if an I/O error occurs */ ClassSpec getClassSpec(String fileName) throws IOException; /** * Get the package specification for the given directory name. Always returns a package specification; this * method cannot be used to test for the existence of a package. A package spec should always be acquired from * the same resource loader which provided the class specification. The directory name will always be specified * using "{@code /}" separators. * * @param name the directory name * @return the package specification * @throws IOException if an I/O error occurs */ PackageSpec getPackageSpec(String name) throws IOException; /** * Get a resource with the given name. If no such resource is available, {@code null} is returned. * The resource name will always be specified using "{@code /}" separators for the directory segments. * * @param name the resource name * @return the resource, or {@code null} if it is not available */ Resource getResource(String name); /** * Get the absolute physical filesystem path for a library with the given name. The resultant path should be * path-separated using "{@code /}" characters. * * @param name the name * @return the path or {@code null} if the library is not present */ String getLibrary(String name); /** * Get the collection of resource paths. Called one time only when the resource loader is initialized. The * paths should use "{@code /}" characters to separate the path segments. * * @return the resource paths */ Collection getPaths(); }jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ResourceLoaderSpec.java000066400000000000000000000045471257205723500277670ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; /** * A specification of a resource loader within a module. A resource loader may optionally be associated with a * path filter which can be used to decide which paths of a resource loader to include. * * @apiviz.exclude * * @author David M. Lloyd */ public final class ResourceLoaderSpec { private final ResourceLoader resourceLoader; private final PathFilter pathFilter; ResourceLoaderSpec(final ResourceLoader resourceLoader, final PathFilter pathFilter) { this.resourceLoader = resourceLoader; this.pathFilter = pathFilter; } /** * Construct a new instance. * * @param resourceLoader the resource loader to include * @param pathFilter the path filter to apply to the resource loader's paths * @return the specification */ public static ResourceLoaderSpec createResourceLoaderSpec(final ResourceLoader resourceLoader, final PathFilter pathFilter) { return new ResourceLoaderSpec(resourceLoader, pathFilter); } /** * Construct a new instance which accepts all paths in the resource loader. * * @param resourceLoader the resource loader to include * @return the specification */ public static ResourceLoaderSpec createResourceLoaderSpec(final ResourceLoader resourceLoader) { return new ResourceLoaderSpec(resourceLoader, PathFilters.acceptAll()); } ResourceLoader getResourceLoader() { return resourceLoader; } PathFilter getPathFilter() { return pathFilter; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ResourceLoaders.java000066400000000000000000000113541257205723500273310ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.security.AccessController; import java.util.jar.JarFile; import org.jboss.modules.filter.PathFilter; /** * Static factory methods for various types of resource loaders. * * @apiviz.exclude * * @author David M. Lloyd */ public final class ResourceLoaders { static final boolean USE_INDEXES; static final boolean WRITE_INDEXES; static { USE_INDEXES = Boolean.parseBoolean(AccessController.doPrivileged(new PropertyReadAction("jboss.modules.use-indexes", "false"))); WRITE_INDEXES = USE_INDEXES && Boolean.parseBoolean(AccessController.doPrivileged(new PropertyReadAction("jboss.modules.write-indexes", "false"))); } private ResourceLoaders() { } /** * Create a filesystem-backed resource loader with support for native libraries. Created classes * have a code source with a {@code file:} URL. * * @param name the name of the resource root * @param root the root file of the resource loader * @return the resource loader */ public static ResourceLoader createFileResourceLoader(final String name, final File root) { return new FileResourceLoader(name, root, AccessController.getContext()); } /** * Create a filesystem-backed iterable resource loader with support for native libraries. Created classes * have a code source with a {@code file:} URL. * * @param name the name of the resource root * @param root the root file of the resource loader * @return the resource loader */ public static IterableResourceLoader createIterableFileResourceLoader(final String name, final File root) { return new FileResourceLoader(name, root, AccessController.getContext()); } /** * Create a JAR-backed resource loader. JAR resource loaders do not have native library support. * Created classes have a code source with a {@code jar:} URL; nested JARs are not supported. * * @param name the name of the resource root * @param jarFile the backing JAR file * @return the resource loader */ public static ResourceLoader createJarResourceLoader(final String name, final JarFile jarFile) { return new JarFileResourceLoader(name, jarFile); } /** * Create a JAR-backed iterable resource loader. JAR resource loaders do not have native library support. * Created classes have a code source with a {@code jar:} URL; nested JARs are not supported. * * @param name the name of the resource root * @param jarFile the backing JAR file * @return the resource loader */ public static IterableResourceLoader createIterableJarResourceLoader(final String name, final JarFile jarFile) { return new JarFileResourceLoader(name, jarFile); } /** * Create a filtered view of a resource loader, which allows classes to be included or excluded on a name basis. * The given filter is matched against the actual class or resource name, not the directory name. * * @param pathFilter the path filter to apply * @param originalLoader the original loader to apply to * @return the filtered resource loader */ public static ResourceLoader createFilteredResourceLoader(final PathFilter pathFilter, final ResourceLoader originalLoader) { return new FilteredResourceLoader(pathFilter, originalLoader); } /** * Create a filtered view of an iterable resource loader, which allows classes to be included or excluded on a name basis. * The given filter is matched against the actual class or resource name, not the directory name. * * @param pathFilter the path filter to apply * @param originalLoader the original loader to apply to * @return the filtered resource loader */ public static IterableResourceLoader createIterableFilteredResourceLoader(final PathFilter pathFilter, final IterableResourceLoader originalLoader) { return new FilteredIterableResourceLoader(pathFilter, originalLoader); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/SecurityActions.java000066400000000000000000000044461257205723500273640ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.security.PrivilegedAction; import static java.lang.System.getSecurityManager; import static java.lang.Thread.currentThread; import static java.security.AccessController.doPrivileged; /** * This class must not be public. * * @author David M. Lloyd */ final class SecurityActions { private static final PrivilegedAction GET_LOADER_ACTION = new PrivilegedAction() { public ClassLoader run() { return currentThread().getContextClassLoader(); } }; static ClassLoader setContextClassLoader(final ClassLoader classLoader) { final SecurityManager sm = getSecurityManager(); if (sm != null) { return doPrivileged(new PrivilegedAction() { public ClassLoader run() { try { return currentThread().getContextClassLoader(); } finally { currentThread().setContextClassLoader(classLoader); } } }); } else { try { return currentThread().getContextClassLoader(); } finally { currentThread().setContextClassLoader(classLoader); } } } static ClassLoader getContextClassLoader() { final SecurityManager sm = getSecurityManager(); if (sm != null) { return doPrivileged(GET_LOADER_ACTION); } else { return currentThread().getContextClassLoader(); } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/StartTimeHolder.java000066400000000000000000000014751257205723500273050ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; final class StartTimeHolder { static final long START_TIME = System.currentTimeMillis(); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/StreamUtil.java000066400000000000000000000056001257205723500263160ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /** * @author David M. Lloyd */ final class StreamUtil { static void copy(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[16384]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } out.flush(); } static void safeClose(Closeable closeable) { if (closeable != null) try { closeable.close(); } catch (Throwable ignored) {} } // ZipFile didn't implement Closeable in 1.6 static void safeClose(ZipFile closeable) { if (closeable != null) try { closeable.close(); } catch (Throwable ignored) {} } static final void unzip(File src, File destDir) throws IOException { final String absolutePath = destDir.getAbsolutePath(); final ZipFile zip = new ZipFile(src); try { final Enumeration entries = zip.entries(); while (entries.hasMoreElements()) { final ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) { continue; } final File fp = new File(absolutePath, PathUtils.canonicalize(PathUtils.relativize(entry.getName()))); final File parent = fp.getParentFile(); if (! parent.exists()) { parent.mkdirs(); } final InputStream is = zip.getInputStream(entry); try { final FileOutputStream os = new FileOutputStream(fp); try { copy(is, os); } finally { safeClose(os); } } finally { safeClose(is); } } } finally { safeClose(zip); } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/URLResource.java000066400000000000000000000024351257205723500264020ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.InputStream; import java.net.URL; /** * @author David M. Lloyd */ final class URLResource implements Resource { private final URL url; public URLResource(final URL url) { this.url = url; } public String getName() { return url.getPath(); } public URL getURL() { return url; } public InputStream openStream() throws IOException { return url.openStream(); } public long getSize() { return 0L; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/UnlockedReadHashMap.java000066400000000000000000000314041257205723500300300ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReferenceArray; /** * A hash map that supports non-blocking, lockless read access. * * @param the key type * @param the value type * @author David M. Lloyd */ final class UnlockedReadHashMap extends AbstractMap implements ConcurrentMap { private static final int DEFAULT_INITIAL_CAPACITY = 128; private static final int MAXIMUM_CAPACITY = 1 << 30; private static final float DEFAULT_LOAD_FACTOR = 0.60f; // Final fields (thread-safe) private final Object writeLock = new Object(); private final Set> entrySet = new EntrySet(); private final float loadFactor; // Volatile fields (writes protected by {@link #writeLock}) private volatile int size; private volatile AtomicReferenceArray[]> table; // Raw fields (reads and writes protected by {@link #writeLock} private int threshold; public UnlockedReadHashMap(int initialCapacity, final float loadFactor) { if (initialCapacity < 0) { throw new IllegalArgumentException("Initial capacity must be > 0"); } if (initialCapacity > MAXIMUM_CAPACITY) { initialCapacity = MAXIMUM_CAPACITY; } if (loadFactor <= 0 || Float.isNaN(loadFactor)) { throw new IllegalArgumentException("Load factor must be > 0.0f"); } int capacity = 1; while (capacity < initialCapacity) { capacity <<= 1; } this.loadFactor = loadFactor; synchronized (writeLock) { threshold = (int)(capacity * loadFactor); table = new AtomicReferenceArray[]>(capacity); } } public UnlockedReadHashMap(final float loadFactor) { this(DEFAULT_INITIAL_CAPACITY, loadFactor); } public UnlockedReadHashMap(final int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } public UnlockedReadHashMap() { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); } @SuppressWarnings( { "unchecked" }) private void resize() { assert Thread.holdsLock(writeLock); final AtomicReferenceArray[]> oldTable = table; final int oldCapacity = oldTable.length(); if (oldCapacity == MAXIMUM_CAPACITY) { return; } final int newCapacity = oldCapacity << 1; final AtomicReferenceArray[]> newTable = new AtomicReferenceArray[]>(newCapacity); final int newThreshold = (int)(newCapacity * loadFactor); for (int i = 0; i < oldCapacity; i ++) { final Item[] items = oldTable.get(i); if (items != null) { final int length = items.length; for (int j = 0; j < length; j++) { Item item = items[j]; final int hc = item.hashCode() & (newCapacity - 1); final Item[] old = newTable.get(hc); if (old == null) { newTable.lazySet(hc, new Item[] { item }); } else { final int oldLen = old.length; final Item[] copy = Arrays.copyOf(old, oldLen + 1); copy[oldLen] = item; newTable.lazySet(hc, copy); } } } } table = newTable; threshold = newThreshold; } private static Item doGet(final AtomicReferenceArray[]> table, final Object key) { Item[] row = doGetRow(table, key); return row == null ? null : doGet(row, key); } private static Item[] doGetRow(final AtomicReferenceArray[]> table, final Object key) { final int hc = getIndex(table, key); return doGetRow(table, hc); } private static int getIndex(final AtomicReferenceArray[]> table, final Object key) { return key.hashCode() & (table.length() - 1); } private static Item[] doGetRow(final AtomicReferenceArray[]> table, final int hc) { return table.get(hc); } private static Item doGet(Item[] row, Object key) { for (Item item : row) { if (item.key.equals(key)) { return item; } } return null; } private V doPut(AtomicReferenceArray[]> table, K key, V value, boolean ifAbsent) { final int hc = getIndex(table, key); final Item[] old = doGetRow(table, hc); if (old == null) { @SuppressWarnings( { "unchecked" }) final Item[] newRow = new Item[] { new Item(key, value) }; table.set(hc, newRow); if (size++ == threshold) { resize(); } return null; } else { final Item item = doGet(old, key); if (item != null) { try { return item.value; } finally { if (! ifAbsent) item.value = value; } } final int oldLen = old.length; final Item[] newRow = Arrays.copyOf(old, oldLen + 1); newRow[oldLen] = new Item(key, value); table.set(hc, newRow); if (size++ == threshold) { resize(); } return null; } } private static Item[] remove(Item[] row, int idx) { final int len = row.length; assert idx < len; if (len == 1) { return null; } @SuppressWarnings("unchecked") Item[] newRow = new Item[len - 1]; if (idx > 0) { System.arraycopy(row, 0, newRow, 0, idx); } if (idx < len - 1) { System.arraycopy(row, idx + 1, newRow, idx, len - 1 - idx); } return newRow; } public Set> entrySet() { return entrySet; } public int size() { return size; } public boolean containsKey(final Object key) { if (key == null) { return false; } final Item item = doGet(table, key); return item != null; } public V get(final Object key) { if (key == null) { return null; } final Item item = doGet(table, key); return item == null ? null : item.value; } public V put(final K key, final V value) { if (key == null) { throw new IllegalArgumentException("key is null"); } synchronized (writeLock) { return doPut(table, key, value, false); } } public V remove(final Object key) { if (key == null) { return null; } synchronized (writeLock) { final int hc = getIndex(table, key); final Item[] row = doGetRow(table, hc); if (row == null) { return null; } final int rowLen = row.length; for (int i = 0; i < rowLen; i++) { final Item item = row[i]; if (item.key.equals(key)) { table.set(hc, remove(row, i)); size --; return item.value; } } return null; } } public void clear() { synchronized (writeLock) { table = new AtomicReferenceArray[]>(table.length()); size = 0; } } public V putIfAbsent(final K key, final V value) { if (key == null) { throw new IllegalArgumentException("key is null"); } synchronized (writeLock) { return doPut(table, key, value, true); } } public boolean remove(final Object key, final Object value) { if (key == null) { return false; } synchronized (writeLock) { final int hc = getIndex(table, key); final Item[] row = doGetRow(table, hc); if (row == null) { return false; } final int rowLen = row.length; for (int i = 0; i < rowLen; i++) { final Item item = row[i]; if (item.key.equals(key) && (value == null ? item.value == null : value.equals(item.value))) { table.set(hc, remove(row, i)); size --; return true; } } return false; } } public boolean replace(final K key, final V oldValue, final V newValue) { if (key == null) { return false; } synchronized (writeLock) { final Item item = doGet(table, key); if (item != null) { if (oldValue == null ? item.value == null : oldValue.equals(item.value)) { item.value = newValue; return true; } } return false; } } public V replace(final K key, final V value) { if (key == null) { return null; } synchronized (writeLock) { final Item item = doGet(table, key); if (item != null) try { return item.value; } finally { item.value = value; } return null; } } private final class EntrySet extends AbstractSet> implements Set> { public Iterator> iterator() { return new EntryIterator(); } public int size() { return UnlockedReadHashMap.this.size(); } } private final class EntryIterator implements Iterator> { private final AtomicReferenceArray[]> table = UnlockedReadHashMap.this.table; private int tableIdx; private int itemIdx; private Item next; public boolean hasNext() { while (next == null) { if (table.length() == tableIdx) { return false; } final Item[] items = table.get(tableIdx); if (items != null) { final int len = items.length; if (itemIdx < len) { next = items[itemIdx++]; return true; } } itemIdx = 0; tableIdx++; } return true; } public Entry next() { if (hasNext()) try { return next; } finally { next = null; } throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } } private static final class Item implements Entry { private final K key; private volatile V value; private Item(final K key, final V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } public V setValue(final V value) { try { return this.value; } finally { this.value = value; } } public int hashCode() { return key.hashCode(); } public boolean equals(final Object obj) { return obj instanceof Item && equals((Item) obj); } public boolean equals(final Item obj) { return obj != null && obj.key.equals(key); } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/_private/000077500000000000000000000000001257205723500251725ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/_private/ModulesPrivateAccess.java000066400000000000000000000021131257205723500321170ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules._private; import org.jboss.modules.Module; import org.jboss.modules.ModuleClassLoader; /** * Private-access methods for modules. User classes cannot acquire an instance * of this class. * * @author David M. Lloyd */ public interface ModulesPrivateAccess { ModuleClassLoader getClassLoaderOf(Module module); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/000077500000000000000000000000001257205723500246465ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/AggregatePathFilter.java000066400000000000000000000050371257205723500313670ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; import java.util.Arrays; /** * PathFilter implementation that aggregates multiple other filters. * * @author John E. Bailey * @author David M. Lloyd */ final class AggregatePathFilter implements PathFilter { private final PathFilter[] delegates; private final boolean any; private final int hashCode; /** * Construct a new instance. * * @param any {@code true} if this is an "any" filter, {@code false} if this an "all" filter * @param delegates the delegate filter list */ AggregatePathFilter(final boolean any, final PathFilter... delegates) { this.any = any; this.delegates = delegates; hashCode = Boolean.valueOf(any).hashCode() ^ Arrays.hashCode(delegates); } /** {@inheritDoc} */ @Override public boolean accept(String path) { for (PathFilter filter : delegates) { if (filter.accept(path) == any) { return any; } } return ! any; } public int hashCode() { return hashCode; } public boolean equals(final Object obj) { return obj instanceof AggregatePathFilter && equals((AggregatePathFilter) obj); } public boolean equals(final AggregatePathFilter obj) { return obj != null && obj.any == any && Arrays.equals(obj.delegates, delegates); } public String toString() { final StringBuilder b = new StringBuilder(); b.append(any ? "Any " : "All ").append("of ("); for (int idx = 0; idx < delegates.length; idx++) { final PathFilter delegate = delegates[idx]; b.append(delegate); if (idx < delegates.length - 1) { b.append(','); } } b.append(')'); return b.toString(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/BooleanClassFilter.java000066400000000000000000000027121257205723500312260ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * @author David M. Lloyd */ final class BooleanClassFilter implements ClassFilter { private final boolean result; private BooleanClassFilter(final boolean result) { this.result = result; } public boolean accept(final String path) { return result; } static final BooleanClassFilter TRUE = new BooleanClassFilter(true); static final BooleanClassFilter FALSE = new BooleanClassFilter(false); public int hashCode() { return Boolean.valueOf(result).hashCode(); } public boolean equals(final Object obj) { return obj == this; } public String toString() { return result ? "Accept" : "Reject"; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/BooleanPathFilter.java000066400000000000000000000027731257205723500310640ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * @author David M. Lloyd */ final class BooleanPathFilter implements PathFilter { private final boolean result; private BooleanPathFilter(final boolean result) { this.result = result; } public boolean accept(final String path) { return result; } static final BooleanPathFilter TRUE = new BooleanPathFilter(true); static final BooleanPathFilter FALSE = new BooleanPathFilter(false); public int hashCode() { return Boolean.valueOf(result).hashCode(); } public boolean equals(final Object obj) { return obj == this; } public String toString() { return result ? "Accept" : "Reject"; } boolean getResult() { return result; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/ChildPathFilter.java000066400000000000000000000027771257205723500305340ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * @author David M. Lloyd */ final class ChildPathFilter implements PathFilter { private final String prefix; ChildPathFilter(final String path) { prefix = path.charAt(path.length() - 1) == '/' ? path : path + "/"; } public boolean accept(final String path) { return path.startsWith(prefix); } public boolean equals(final Object obj) { return obj instanceof ChildPathFilter && equals((ChildPathFilter) obj); } public boolean equals(final ChildPathFilter obj) { return obj != null && obj.prefix.equals(prefix); } public String toString() { return "children of \"" + prefix + "\""; } public int hashCode() { return prefix.hashCode(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/ClassFilter.java000066400000000000000000000024011257205723500277210ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * Filter used to determine whether a class name should be included or excluded from imports and exports. * * @author David M. Lloyd */ public interface ClassFilter { /** * Determine whether a class name should be accepted by this filter. The class name is qualified with a dot-separated * package name. * * @param className the class name * @return {@code true} to accept the class, {@code false} otherwise */ boolean accept(String className); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/ClassFilters.java000066400000000000000000000033511257205723500301110ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * Static factory methods for class filter types. * * @author David M. Lloyd */ public final class ClassFilters { private ClassFilters() { } /** * Get a filter which always returns {@code true}. * * @return the accept-all filter */ public static ClassFilter acceptAll() { return BooleanClassFilter.TRUE; } /** * Get a filter which always returns {@code false}. * * @return the reject-all filter */ public static ClassFilter rejectAll() { return BooleanClassFilter.FALSE; } /** * Get a class filter which uses a resource path filter to filter classes. * * @param resourcePathFilter the resource path filter * @return the class filter */ public static ClassFilter fromResourcePathFilter(final PathFilter resourcePathFilter) { return resourcePathFilter == PathFilters.acceptAll() ? acceptAll() : new PathClassFilter(resourcePathFilter); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/EqualsPathFilter.java000066400000000000000000000030541257205723500307300ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * @author David M. Lloyd */ final class EqualsPathFilter implements PathFilter { private final String path; EqualsPathFilter(final String path) { if (path == null) { throw new IllegalArgumentException("path is null"); } this.path = path; } public boolean accept(final String path) { return path.equals(this.path); } public boolean equals(final Object obj) { return obj instanceof EqualsPathFilter && equals((EqualsPathFilter) obj); } public boolean equals(final EqualsPathFilter obj) { return obj != null && obj.path.equals(path); } public String toString() { return "equals \"" + path + "\""; } public int hashCode() { return path.hashCode() + 7; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/GlobPathFilter.java000066400000000000000000000120071257205723500303570ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Default implementation of PathFilter. Uses glob based includes and excludes to determine whether to export. * * @author John E. Bailey * @author David M. Lloyd */ final class GlobPathFilter implements PathFilter { private static final Pattern GLOB_PATTERN = Pattern.compile("(\\*\\*?)|(\\?)|(\\\\.)|(/+)|([^*?]+)"); private final String glob; private final Pattern pattern; /** * Construct a new instance. * * @param glob the path glob to match */ GlobPathFilter(final String glob) { pattern = getGlobPattern(glob); this.glob = glob; } /** * Determine whether a path should be accepted. * * @param path the path to check * @return true if the path should be accepted, false if not */ public boolean accept(final String path) { return pattern.matcher(path).matches(); } /** * Get a regular expression pattern which accept any path names which match the given glob. The glob patterns * function similarly to {@code ant} file patterns. Valid metacharacters in the glob pattern include: *
    *
  • "\" - escape the next character (treat it literally, even if it is itself a recognized metacharacter)
  • *
  • "?" - match any non-slash character
  • *
  • "*" - match zero or more non-slash characters
  • *
  • "**" - match zero or more characters, including slashes
  • *
  • "/" - match one or more slash characters. Consecutive {@code /} characters are collapsed down into one.
  • *
* In addition, any glob pattern matches all subdirectories thereof. A glob pattern ending in {@code /} is equivalent * to a glob pattern ending in /** in that the named directory is not itself included in the glob. *

* See also: "Patterns" in the Ant Manual * * @param glob the glob to match * * @return the pattern */ private static Pattern getGlobPattern(final String glob) { StringBuilder patternBuilder = new StringBuilder(); final Matcher m = GLOB_PATTERN.matcher(glob); boolean lastWasSlash = false; while (m.find()) { lastWasSlash = false; String grp; if ((grp = m.group(1)) != null) { // match a * or ** if (grp.length() == 2) { // it's a ** patternBuilder.append(".*"); } else { // it's a * patternBuilder.append("[^/]*"); } } else if ((grp = m.group(2)) != null) { // match a '?' glob pattern; any non-slash character patternBuilder.append("[^/]"); } else if ((grp = m.group(3)) != null) { // backslash-escaped value patternBuilder.append(Pattern.quote(m.group().substring(1))); } else if ((grp = m.group(4)) != null) { // match any number of / chars patternBuilder.append("/+"); lastWasSlash = true; } else { // some other string patternBuilder.append(Pattern.quote(m.group())); } } if (lastWasSlash) { // ends in /, append ** patternBuilder.append(".*"); } else { patternBuilder.append("(?:/.*)?"); } return Pattern.compile(patternBuilder.toString()); } public int hashCode() { return glob.hashCode() + 13; } public boolean equals(final Object obj) { return obj instanceof GlobPathFilter && equals((GlobPathFilter) obj); } public boolean equals(final GlobPathFilter obj) { return obj != null && obj.pattern.equals(pattern); } public String toString() { final StringBuilder b = new StringBuilder(); b.append("match "); if (glob != null) { b.append('"').append(glob).append('"'); } else { b.append('/').append(pattern).append('/'); } return b.toString(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/InvertingPathFilter.java000066400000000000000000000035701257205723500314460ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * A path filter which simply inverts the result of another path filter. * * @author David M. Lloyd */ final class InvertingPathFilter implements PathFilter { private final PathFilter delegate; /** * Construct a new instance. * * @param delegate the filter to delegate to */ InvertingPathFilter(final PathFilter delegate) { if (delegate == null) { throw new IllegalArgumentException("delegate is null"); } this.delegate = delegate; } /** {@inheritDoc} */ public boolean accept(final String path) { return ! delegate.accept(path); } PathFilter getDelegate() { return delegate; } public int hashCode() { return 47 + delegate.hashCode(); } public boolean equals(final Object obj) { return obj instanceof InvertingPathFilter && equals((InvertingPathFilter) obj); } public boolean equals(final InvertingPathFilter obj) { return obj != null && obj.delegate.equals(delegate); } public String toString() { return "not " + delegate.toString(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/MultiplePathFilter.java000066400000000000000000000051621257205723500312730ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; import java.util.Arrays; /** * @author David M. Lloyd */ final class MultiplePathFilter implements PathFilter { private final PathFilter[] filters; private final boolean[] includeFlag; private final boolean defaultVal; private final int hashCode; MultiplePathFilter(final PathFilter[] filters, final boolean[] includeFlag, final boolean defaultVal) { this.filters = filters; this.includeFlag = includeFlag; this.defaultVal = defaultVal; hashCode = Boolean.valueOf(defaultVal).hashCode() * 13 + (Arrays.hashCode(includeFlag) * 13 + (Arrays.hashCode(filters))); } public boolean accept(final String path) { final int len = filters.length; for (int i = 0; i < len; i++) { if (filters[i].accept(path)) return includeFlag[i]; } return defaultVal; } public String toString() { StringBuilder builder = new StringBuilder(); builder.append("multi-path filter {"); int len = filters.length; for (int i = 0; i < len; i++) { final PathFilter filter = filters[i]; final boolean include = includeFlag[i]; builder.append(include ? "include " : "exclude "); builder.append(filter); builder.append(", "); } builder.append("default ").append(defaultVal ? "accept" : "reject"); builder.append('}'); return builder.toString(); } public int hashCode() { return hashCode; } public boolean equals(Object other) { return other instanceof MultiplePathFilter && equals((MultiplePathFilter)other); } public boolean equals(MultiplePathFilter other) { return this == other || other != null && Arrays.equals(filters, other.filters) && Arrays.equals(includeFlag, other.includeFlag) && defaultVal == other.defaultVal; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/MultiplePathFilterBuilder.java000066400000000000000000000052341257205723500326020ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; import java.util.ArrayList; import java.util.List; /** * A builder for a multiple-path filter. * * @apiviz.exclude * @see PathFilters#multiplePathFilterBuilder(boolean) */ public class MultiplePathFilterBuilder { private final List filters = new ArrayList(); private final List includeFlags = new ArrayList(); private final boolean defaultVal; MultiplePathFilterBuilder(final boolean defaultVal) { this.defaultVal = defaultVal; } /** * Add a filter to this builder. * * @param filter the filter to add * @param include {@code true} if matching paths should be included, {@code false} for excluded */ public void addFilter(final PathFilter filter, final boolean include) { if (filter == null) { throw new IllegalArgumentException("filter is null"); } filters.add(filter); includeFlags.add(Boolean.valueOf(include)); } /** * Create the path filter from this builder's current state. * * @return the path filter */ public PathFilter create() { final PathFilter[] filters = this.filters.toArray(new PathFilter[this.filters.size()]); final boolean[] includeFlags = new boolean[this.includeFlags.size()]; for (int i = 0, includeFlagsSize = this.includeFlags.size(); i < includeFlagsSize; i++) { includeFlags[i] = this.includeFlags.get(i).booleanValue(); } if (filters.length == 0) { return defaultVal ? PathFilters.acceptAll() : PathFilters.rejectAll(); } else { return new MultiplePathFilter(filters, includeFlags, defaultVal); } } /** * Determine if this filter builder is empty (i.e. has no path filters set on it). * * @return {@code true} if this builder is empty, {@code false} otherwise */ public boolean isEmpty() { return filters.isEmpty(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/PathClassFilter.java000066400000000000000000000022501257205723500305400ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * @author David M. Lloyd */ class PathClassFilter implements ClassFilter { private final PathFilter resourcePathFilter; public PathClassFilter(final PathFilter resourcePathFilter) { this.resourcePathFilter = resourcePathFilter; } public boolean accept(final String className) { return resourcePathFilter.accept(className.replace('.', '/').concat(".class")); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/PathFilter.java000066400000000000000000000031721257205723500275560ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; /** * Filter used to determine whether a path should be included or excluded from imports and exports. * * @author John Bailey */ public interface PathFilter { /** * Determine whether a path should be accepted. The given name is a path separated * by "{@code /}" characters. * * @param path the path to check * @return true if the path should be accepted, false if not */ boolean accept(String path); /** * Calculate a unique hash code for this path filter. Equal path filters must yield identical hash codes. * * @return the hash code */ int hashCode(); /** * Determine whether this filter is equal to another. Filters must implement meaningful (non-identity) equality * semantics. * * @param other the other object * @return {@code true} if this filter is the same */ boolean equals(Object other); }jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/PathFilters.java000066400000000000000000000264401257205723500277440ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import org.jboss.modules.Resource; /** * Static factory methods for path filter types. * * @author David M. Lloyd */ public final class PathFilters { private PathFilters() {} /** * Get a path filter which returns {@code true} if all of the given filters return {@code true}. * * @param filters the filters * @return the "all" filter */ public static PathFilter all(PathFilter... filters) { return new AggregatePathFilter(false, filters); } /** * Get a path filter which returns {@code true} if all of the given filters return {@code true}. * * @param filters the filters * @return the "all" filter */ public static PathFilter all(Collection filters) { return all(filters.toArray(new PathFilter[filters.size()])); } /** * Get a path filter which returns {@code true} if any of the given filters return {@code true}. * * @param filters the filters * @return the "any" filter */ public static PathFilter any(PathFilter... filters) { return new AggregatePathFilter(true, filters); } /** * Get a path filter which returns {@code true} if any of the given filters return {@code true}. * * @param filters the filters * @return the "any" filter */ public static PathFilter any(Collection filters) { return any(filters.toArray(new PathFilter[filters.size()])); } /** * Get a path filter which returns {@code true} if none of the given filters return {@code true}. * * @param filters the filters * @return the "none" filter */ public static PathFilter none(PathFilter... filters) { return not(any(filters)); } /** * Get a path filter which returns {@code true} if none of the given filters return {@code true}. * * @param filters the filters * @return the "none" filter */ public static PathFilter none(Collection filters) { return not(any(filters)); } /** * Get a path filter which is {@code true} when the given filter is {@code false}, and vice-versa. * * @param filter the filter * @return the inverting filter */ public static PathFilter not(PathFilter filter) { if (filter instanceof BooleanPathFilter) { return booleanFilter(!((BooleanPathFilter) filter).getResult()); } else if (filter instanceof InvertingPathFilter) { return ((InvertingPathFilter) filter).getDelegate(); } else { return new InvertingPathFilter(filter); } } /** * Get a path filter which matches a glob. The given glob is a path separated * by "{@code /}" characters, which may include the special "{@code *}" and "{@code **}" segment strings * which match any directory and any number of nested directories, respectively. * * @param glob the glob * @return a filter which returns {@code true} if the glob matches */ public static PathFilter match(String glob) { return new GlobPathFilter(glob); } /** * Get a path filter which matches an exact path name. * * @param path the path name * @return a filter which returns {@code true} if the path name is an exact match */ public static PathFilter is(String path) { return new EqualsPathFilter(path); } /** * Get a path filter which matches any path which is a child of the given path name (not including the * path name itself). * * @param path the path name * @return a filter which returns {@code true} if the path name is a child of the given path */ public static PathFilter isChildOf(String path) { return new ChildPathFilter(path); } /** * Get a path filter which matches any path which is equal to, or a child of, the given path name. * * @param path the path name * @return a filter which returns {@code true} if the path name is equal to, or a child of, the given path */ public static PathFilter isOrIsChildOf(String path) { return any(is(path), isChildOf(path)); } /** * Get a builder for a multiple-path filter. Such a filter contains multiple filters, each associated * with a flag which indicates that matching paths should be included or excluded. * * @param defaultValue the value to return if none of the nested filters match * @return the builder */ public static MultiplePathFilterBuilder multiplePathFilterBuilder(boolean defaultValue) { return new MultiplePathFilterBuilder(defaultValue); } private static BooleanPathFilter booleanFilter(boolean val) { return val ? BooleanPathFilter.TRUE : BooleanPathFilter.FALSE; } /** * Get a filter which always returns {@code true}. * * @return the accept-all filter */ public static PathFilter acceptAll() { return BooleanPathFilter.TRUE; } /** * Get a filter which always returns {@code false}. * * @return the reject-all filter */ public static PathFilter rejectAll() { return BooleanPathFilter.FALSE; } /** * Get a filter which returns {@code true} if the tested path is contained within the given set. * Each member of the set is a path separated by "{@code /}" characters; {@code null}s are disallowed. * * @param paths the path set * @return the filter */ public static PathFilter in(Set paths) { return new SetPathFilter(new HashSet(paths)); } /** * Get a filter which returns {@code true} if the tested path is contained within the given collection. * Each member of the collection is a path separated by "{@code /}" characters; {@code null}s are disallowed. * * @param paths the path collection * @return the filter */ public static PathFilter in(Collection paths) { return new SetPathFilter(new HashSet(paths)); } /** * Get a filtered view of a resource iteration. Only resources which pass the given filter are accepted. * * @param filter the filter to check * @param original the original iterator * @return the filtered iterator */ public static Iterator filtered(final PathFilter filter, final Iterator original) { return new Iterator() { private Resource next; public boolean hasNext() { Resource next; while (this.next == null && original.hasNext()) { next = original.next(); if (filter.accept(next.getName())) { this.next = next; } } return this.next != null; } public Resource next() { if (! hasNext()) { throw new NoSuchElementException(); } try { return next; } finally { next = null; } } public void remove() { original.remove(); } }; } private static final PathFilter defaultImportFilter; private static final PathFilter defaultImportFilterWithServices; private static final PathFilter metaInfFilter; private static final PathFilter metaInfSubdirectoriesFilter; private static final PathFilter metaInfServicesFilter; private static final PathFilter metaInfSubdirectoriesWithoutMetaInfFilter; static { final PathFilter metaInfChildren = isChildOf("META-INF"); final PathFilter metaInf = is("META-INF"); final PathFilter metaInfServicesChildren = isChildOf("META-INF/services"); final PathFilter metaInfServices = is("META-INF/services"); metaInfFilter = metaInf; metaInfSubdirectoriesFilter = metaInfChildren; metaInfServicesFilter = any(metaInfServices, metaInfServicesChildren); final MultiplePathFilterBuilder builder = multiplePathFilterBuilder(true); builder.addFilter(metaInfChildren, false); builder.addFilter(metaInf, false); defaultImportFilter = builder.create(); final MultiplePathFilterBuilder builder2 = multiplePathFilterBuilder(true); builder2.addFilter(metaInfServices, true); builder2.addFilter(metaInfServicesChildren, true); builder2.addFilter(metaInfChildren, false); builder2.addFilter(metaInf, false); defaultImportFilterWithServices = builder2.create(); final MultiplePathFilterBuilder builder3 = multiplePathFilterBuilder(true); builder2.addFilter(metaInfChildren, true); builder3.addFilter(metaInf, false); metaInfSubdirectoriesWithoutMetaInfFilter = builder3.create(); } /** * Get the default import path filter, which excludes all of {@code META-INF} and its subdirectories. * * @return the default import path filter */ public static PathFilter getDefaultImportFilter() { return defaultImportFilter; } /** * Get the default import-with-services path filter which excludes all of {@code META-INF} and its subdirectories, * with the exception of {@code META-INF/services}. * * @return the default import-with-services path filter */ public static PathFilter getDefaultImportFilterWithServices() { return defaultImportFilterWithServices; } /** * Get a filter which matches the path {@code "META-INF"}. * * @return the filter */ public static PathFilter getMetaInfFilter() { return metaInfFilter; } /** * Get a filter which matches any subdirectory of the path {@code "META-INF"}. * * @return the filter */ public static PathFilter getMetaInfSubdirectoriesFilter() { return metaInfSubdirectoriesFilter; } /** * Get a filter which matches the path {@code "META-INF/services"}. * * @return the filter */ public static PathFilter getMetaInfServicesFilter() { return metaInfServicesFilter; } /** * Get a filter which matches all of {@code META-INF}'s subdirectories, but not {@code META-INF} itself. * * @return the filter */ public static PathFilter getMetaInfSubdirectoriesWithoutMetaInfFilter() { return metaInfSubdirectoriesWithoutMetaInfFilter; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/SetPathFilter.java000066400000000000000000000036201257205723500302300ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.filter; import java.util.Iterator; import java.util.Set; /** * @author David M. Lloyd */ final class SetPathFilter implements PathFilter { private final Set paths; private final int hashCode; SetPathFilter(final Set paths) { this.paths = paths; hashCode = paths.hashCode(); } public boolean accept(final String path) { return paths.contains(path); } public String toString() { final StringBuilder b = new StringBuilder(); b.append("in {"); Iterator iterator = paths.iterator(); while (iterator.hasNext()) { final String path = iterator.next(); b.append(path); if (iterator.hasNext()) { b.append(", "); } } b.append('}'); return b.toString(); } public boolean equals(final Object obj) { return obj instanceof SetPathFilter && equals((SetPathFilter) obj); } public boolean equals(final SetPathFilter obj) { return obj != null && obj.paths.equals(paths); } public int hashCode() { return hashCode; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/filter/package-info.java000066400000000000000000000016571257205723500300460ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ /** * Classes related to filtering. See the {@link PathFilter} interface for the contract of path filters. See * {@link PathFilters} for factory methods for creating simple and complex filters. */ package org.jboss.modules.filter;jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/000077500000000000000000000000001257205723500241425ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/JDKModuleLogger.java000066400000000000000000000146251257205723500277330ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.log; import java.util.logging.Level; import java.util.logging.Logger; import org.jboss.modules.Main; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A {@link ModuleLogger} which logs to a JDK logging category. * * @author David M. Lloyd */ public final class JDKModuleLogger implements ModuleLogger { private static final Level TRACE; private static final Level DEBUG; private static final Level WARN; static { Level trace; Level debug; Level warn; try { trace = Level.parse("TRACE"); } catch (IllegalArgumentException ignored) { trace = Level.FINEST; } try { debug = Level.parse("DEBUG"); } catch (IllegalArgumentException ignored) { debug = Level.FINE; } try { warn = Level.parse("WARN"); } catch (IllegalArgumentException ignored) { warn = Level.WARNING; } TRACE = trace; DEBUG = debug; WARN = warn; } @SuppressWarnings({ "NonConstantLogger" }) private final Logger logger; @SuppressWarnings({ "NonConstantLogger" }) private final Logger defineLogger; /** * Construct a new instance. * * @param logger the main logger to write to * @param defineLogger the main logger to write class-define-related trace messages to */ public JDKModuleLogger(final Logger logger, final Logger defineLogger) { this.logger = logger; this.defineLogger = defineLogger; } /** * Construct a new instance. * * @param category the name of the logger category to write to */ public JDKModuleLogger(final String category) { this(Logger.getLogger(category), Logger.getLogger(category + ".define")); } /** * Construct a new instance using the category {@code org.jboss.modules}. */ public JDKModuleLogger() { this("org.jboss.modules"); } private void doLog(final Level level, final String str) { doLog(level, str, null); } private void doLog(final Level level, final String str, final Throwable t) { try { final ModuleLogRecord rec = new ModuleLogRecord(level, str); rec.setLoggerName(logger.getName()); if (t != null) rec.setThrown(t); logger.log(rec); } catch (Throwable ignored) { } } /** {@inheritDoc} */ public void trace(final String message) { doLog(TRACE, message, null); } /** {@inheritDoc} */ public void trace(final String format, final Object arg1) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, arg1), null); } } /** {@inheritDoc} */ public void trace(final String format, final Object arg1, final Object arg2) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, arg1, arg2)); } } /** {@inheritDoc} */ public void trace(final String format, final Object arg1, final Object arg2, final Object arg3) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, arg1, arg2, arg3)); } } /** {@inheritDoc} */ public void trace(final String format, final Object... args) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, (Object[]) args)); } } /** {@inheritDoc} */ public void trace(final Throwable t, final String message) { doLog(TRACE, message, t); } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object arg1) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, arg1), t); } } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object arg1, final Object arg2) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, arg1, arg2), t); } } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object arg1, final Object arg2, final Object arg3) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, arg1, arg2, arg3), t); } } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object... args) { if (logger.isLoggable(TRACE)) { doLog(TRACE, String.format(format, (Object[]) args), t); } } /** {@inheritDoc} */ public void greeting() { doLog(Level.INFO, String.format("JBoss Modules version %s", Main.getVersionString())); } /** {@inheritDoc} */ public void moduleDefined(final ModuleIdentifier identifier, final ModuleLoader moduleLoader) { if (logger.isLoggable(DEBUG)) { doLog(DEBUG, String.format("Module %s defined by %s", identifier, moduleLoader)); } } public void classDefineFailed(final Throwable throwable, final String className, final Module module) { if (defineLogger.isLoggable(WARN)) { doLog(WARN, String.format("Failed to define class %s in %s", className, module), throwable); } } public void classDefined(final String name, final Module module) { if (defineLogger.isLoggable(TRACE)) { doLog(TRACE, String.format("Defined class %s in %s", name, module)); } } public void providerUnloadable(String name, ClassLoader loader) { if (defineLogger.isLoggable(TRACE)) { doLog(TRACE, String.format("Could not load provider %s in %s", name, loader)); } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/ModuleLogRecord.java000066400000000000000000000062621257205723500300410ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.log; import java.util.logging.LogRecord; import java.util.logging.Level; /** * A log record class which knows how to divine the proper class and method name. */ class ModuleLogRecord extends LogRecord { private static final long serialVersionUID = 542119905844866161L; private boolean resolved; private static final String LOGGER_CLASS_NAME = JDKModuleLogger.class.getName(); ModuleLogRecord(final Level level, final String msg) { super(level, msg); } public String getSourceClassName() { if (! resolved) { resolve(); } return super.getSourceClassName(); } public void setSourceClassName(final String sourceClassName) { resolved = true; super.setSourceClassName(sourceClassName); } public String getSourceMethodName() { if (! resolved) { resolve(); } return super.getSourceMethodName(); } public void setSourceMethodName(final String sourceMethodName) { resolved = true; super.setSourceMethodName(sourceMethodName); } private void resolve() { resolved = true; final StackTraceElement[] stack = new Throwable().getStackTrace(); boolean found = false; for (StackTraceElement element : stack) { final String className = element.getClassName(); if (found) { if (! LOGGER_CLASS_NAME.equals(className)) { setSourceClassName(className); setSourceMethodName(element.getMethodName()); return; } } else { found = LOGGER_CLASS_NAME.equals(className); } } setSourceClassName(""); setSourceMethodName(""); } protected Object writeReplace() { final LogRecord replacement = new LogRecord(getLevel(), getMessage()); replacement.setResourceBundle(getResourceBundle()); replacement.setLoggerName(getLoggerName()); replacement.setMillis(getMillis()); replacement.setParameters(getParameters()); replacement.setResourceBundleName(getResourceBundleName()); replacement.setSequenceNumber(getSequenceNumber()); replacement.setSourceClassName(getSourceClassName()); replacement.setSourceMethodName(getSourceMethodName()); replacement.setThreadID(getThreadID()); replacement.setThrown(getThrown()); return replacement; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/ModuleLogger.java000066400000000000000000000036011257205723500273720ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.log; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A simple Logger abstraction. * * @author thomas.diesler@jboss.com * @author David M. Lloyd */ public interface ModuleLogger { void trace(String message); void trace(String format, Object arg1); void trace(String format, Object arg1, Object arg2); void trace(String format, Object arg1, Object arg2, Object arg3); void trace(String format, Object... args); void trace(Throwable t, String message); void trace(Throwable t, String format, Object arg1); void trace(Throwable t, String format, Object arg1, Object arg2); void trace(Throwable t, String format, Object arg1, Object arg2, Object arg3); void trace(Throwable t, String format, Object... args); void greeting(); void moduleDefined(ModuleIdentifier identifier, final ModuleLoader moduleLoader); void classDefineFailed(Throwable throwable, String className, Module module); void classDefined(String name, Module module); void providerUnloadable(String name, ClassLoader loader); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/NoopModuleLogger.java000066400000000000000000000052761257205723500302400ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.log; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A {@link ModuleLogger} implementation that does not log. * * @author thomas.diesler@jboss.com * @author David M. Lloyd */ public final class NoopModuleLogger implements ModuleLogger { private static ModuleLogger instance = new NoopModuleLogger(); public static ModuleLogger getInstance() { return instance; } @Override public void trace(String message) { } @Override public void trace(final String format, final Object arg1) { } @Override public void trace(final String format, final Object arg1, final Object arg2) { } @Override public void trace(final String format, final Object arg1, final Object arg2, final Object arg3) { } @Override public void trace(final String format, final Object... args) { } @Override public void trace(final Throwable t, final String message) { } @Override public void trace(final Throwable t, final String format, final Object arg1) { } @Override public void trace(final Throwable t, final String format, final Object arg1, final Object arg2) { } @Override public void trace(final Throwable t, final String format, final Object arg1, final Object arg2, final Object arg3) { } @Override public void trace(final Throwable t, final String format, final Object... args) { } @Override public void greeting() { } @Override public void moduleDefined(final ModuleIdentifier identifier, final ModuleLoader moduleLoader) { } @Override public void classDefineFailed(final Throwable throwable, final String className, final Module module) { } @Override public void classDefined(final String name, final Module module) { } @Override public void providerUnloadable(String name, ClassLoader loader) { } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/StreamModuleLogger.java000066400000000000000000000113201257205723500305430ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.log; import java.io.OutputStream; import java.io.PrintStream; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; /** * A {@link ModuleLogger} implementation that logs all output (including trace) to an output or print stream. * * @author thomas.diesler@jboss.com * @author David M. Lloyd */ public final class StreamModuleLogger implements ModuleLogger { private PrintStream print; /** * Construct a new instance. * * @param stream the print stream to write to */ public StreamModuleLogger(PrintStream stream) { if (stream == null) { throw new IllegalArgumentException("stream is null"); } print = new PrintStream(stream); } /** * Construct a new instance. * * @param stream the output stream to write to */ public StreamModuleLogger(OutputStream stream) { this(new PrintStream(stream)); } /** {@inheritDoc} */ public void trace(final String message) { print.print("modules TRACE: "); print.println(message); print.flush(); } /** {@inheritDoc} */ public void trace(final String format, final Object arg1) { print.print("modules TRACE: "); print.printf(format, arg1); print.println(); print.flush(); } /** {@inheritDoc} */ public void trace(final String format, final Object arg1, final Object arg2) { print.print("modules TRACE: "); print.printf(format, arg1, arg2); print.println(); print.flush(); } /** {@inheritDoc} */ public void trace(final String format, final Object arg1, final Object arg2, final Object arg3) { print.print("modules TRACE: "); print.printf(format, arg1, arg2, arg3); print.println(); print.flush(); } /** {@inheritDoc} */ public void trace(final String format, final Object... args) { print.print("modules TRACE: "); print.printf(format, (Object[]) args); print.println(); print.flush(); } /** {@inheritDoc} */ public void trace(final Throwable t, final String message) { print.print("modules TRACE: "); print.print(message); print.print(": "); t.printStackTrace(print); print.flush(); } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object arg1) { print.print("modules TRACE: "); print.printf(format, arg1); print.print(": "); t.printStackTrace(print); print.flush(); } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object arg1, final Object arg2) { print.print("modules TRACE: "); print.printf(format, arg1, arg2); print.print(": "); t.printStackTrace(print); print.flush(); } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object arg1, final Object arg2, final Object arg3) { print.print("modules TRACE: "); print.printf(format, arg1, arg2, arg3); print.print(": "); t.printStackTrace(print); print.flush(); } /** {@inheritDoc} */ public void trace(final Throwable t, final String format, final Object... args) { print.print("modules TRACE: "); print.printf(format, args); print.print(": "); t.printStackTrace(print); print.flush(); } /** {@inheritDoc} */ public void greeting() { } /** {@inheritDoc} */ public void moduleDefined(final ModuleIdentifier identifier, final ModuleLoader moduleLoader) { } /** {@inheritDoc} */ public void classDefineFailed(final Throwable throwable, final String className, final Module module) { } public void classDefined(final String name, final Module module) { } public void providerUnloadable(String name, ClassLoader loader) { } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/log/package-info.java000066400000000000000000000020241257205723500273270ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ /** * The logging interface for JBoss Modules. Logging is abstracted in order to support logging services being provided * by a module. To change the logger in use, use the {@link org.jboss.modules.Module#setModuleLogger(ModuleLogger)} method. * See {@link ModuleLogger} for the logging contract. */ package org.jboss.modules.log;jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/000077500000000000000000000000001257205723500254755ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/DependencyInfo.java000066400000000000000000000102121257205723500312260ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.management; import java.beans.ConstructorProperties; import java.util.List; /** * Information describing a dependency. * * @author David M. Lloyd */ public final class DependencyInfo { private final String dependencyType; private final String exportFilter; private final String importFilter; private final ModuleLoaderMXBean moduleLoader; private final String moduleName; private final boolean optional; private final String localLoader; private final List localLoaderPaths; /** * Construct a new instance. * * @param dependencyType the dependency type class name * @param exportFilter the export filter, as a string * @param importFilter the import filter, as a string * @param moduleLoader the module loader MXBean of this dependency * @param moduleName the module name, as a string * @param optional {@code true} if this is an optional dependency * @param localLoader the local loader type class name * @param localLoaderPaths the list of paths made available by the local loader */ @ConstructorProperties({"dependencyType", "exportFilter", "importFilter", "moduleLoader", "moduleName", "optional", "localLoader", "localLoaderPaths"}) public DependencyInfo(final String dependencyType, final String exportFilter, final String importFilter, final ModuleLoaderMXBean moduleLoader, final String moduleName, final boolean optional, final String localLoader, final List localLoaderPaths) { this.dependencyType = dependencyType; this.exportFilter = exportFilter; this.importFilter = importFilter; this.moduleLoader = moduleLoader; this.moduleName = moduleName; this.optional = optional; this.localLoader = localLoader; this.localLoaderPaths = localLoaderPaths; } /** * Get the dependency type class name. * * @return the dependency type class name */ public String getDependencyType() { return dependencyType; } /** * Get the export filter, as a string. * * @return the export filter, as a string */ public String getExportFilter() { return exportFilter; } /** * Get the import filter, as a string. * * @return the import filter, as a string */ public String getImportFilter() { return importFilter; } /** * Get the module loader MXBean of this dependency. * * @return the module loader MXBean of this dependency */ public ModuleLoaderMXBean getModuleLoader() { return moduleLoader; } /** * Get the module name, as a string. * * @return the module name, as a string */ public String getModuleName() { return moduleName; } /** * Determine whether this is an optional dependency. * * @return {@code true} if this is an optional dependency */ public boolean isOptional() { return optional; } /** * Get the local loader type class name. * * @return the local loader type class name */ public String getLocalLoader() { return localLoader; } /** * Get the list of paths made available by the local loader. * * @return the list of paths made available by the local loader */ public List getLocalLoaderPaths() { return localLoaderPaths; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/ModuleInfo.java000066400000000000000000000071501257205723500304040ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.management; import java.beans.ConstructorProperties; import java.util.List; /** * Management information about a module instance. * * @author David M. Lloyd */ public final class ModuleInfo { private final String name; private final ModuleLoaderMXBean moduleLoader; private final List dependencies; private final List resourceLoaders; private final String mainClass; private final String classLoader; private final String fallbackLoader; /** * Construct a new instance. * * @param name the module name * @param moduleLoader the module loader * @param dependencies the dependencies list * @param resourceLoaders the resource loaders list * @param mainClass the main class name * @param classLoader the class loader * @param fallbackLoader the fallback loader */ @ConstructorProperties({"name", "moduleLoader", "dependencies", "resourceLoaders", "mainClass", "classLoader", "fallbackLoader"}) public ModuleInfo(final String name, final ModuleLoaderMXBean moduleLoader, final List dependencies, final List resourceLoaders, final String mainClass, final String classLoader, final String fallbackLoader) { this.name = name; this.moduleLoader = moduleLoader; this.dependencies = dependencies; this.resourceLoaders = resourceLoaders; this.mainClass = mainClass; this.classLoader = classLoader; this.fallbackLoader = fallbackLoader; } /** * Get the name of the corresponding module. * * @return the name of the corresponding module */ public String getName() { return name; } /** * Get the associated module loader MXBean. * * @return the associated module loader MXBean */ public ModuleLoaderMXBean getModuleLoader() { return moduleLoader; } /** * Get the dependency information list. * * @return the dependency information list */ public List getDependencies() { return dependencies; } /** * Get the resource loader information list. * * @return the resource loader information list */ public List getResourceLoaders() { return resourceLoaders; } /** * Get the main class name. * * @return the main class name */ public String getMainClass() { return mainClass; } /** * Get the class loader (as a string). * * @return the class loader (as a string) */ public String getClassLoader() { return classLoader; } /** * Get the fallback loader (as a string). * * @return the fallback loader (as a string) */ public String getFallbackLoader() { return fallbackLoader; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/ModuleLoaderMXBean.java000066400000000000000000000105121257205723500317460ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.management; import java.util.List; import java.util.SortedMap; /** * An MXBean for getting runtime information about a module loader. * * @author David M. Lloyd */ public interface ModuleLoaderMXBean { /** * Get a description of this module loader. * * @return a description of this module loader */ String getDescription(); /** * Get the estimated CPU time (in nanoseconds) spent linking in the life of this module loader. * * @return the estimated time in nanoseconds */ long getLinkTime(); /** * Get the estimated CPU time (in nanoseconds) spent loading modules into this loader. * * @return the estimated time in nanoseconds */ long getLoadTime(); /** * Get the estimated CPU time (in nanoseconds) spent defining classes for this loader. * * @return the estimated time in nanoseconds */ long getClassDefineTime(); /** * Get the number of times that dependencies of a module from this loader have been scanned. * * @return the count */ int getScanCount(); /** * Get the number of modules currently loaded. * * @return the loaded module count */ int getLoadedModuleCount(); /** * Get the number of times a class was defined by two threads at once. * * @return the race count */ int getRaceCount(); /** * Get the number of classes defined in this module loader. * * @return the number of classes defined in this module loader */ int getClassCount(); /** * Obtain a list of the current module names. * * @return the module names */ List queryLoadedModuleNames(); /** * Dump all information for a single module as a string. * * @param name the module name * @return the string of module information */ String dumpModuleInformation(String name); /** * Dump all information for all modules as a string. * * @return the string of module information */ String dumpAllModuleInformation(); /** * Attempt to unload a module from this module loader. * * @param name the string form of the module identifier to unload * @return {@code true} if the module was unloaded */ boolean unloadModule(String name); /** * Attempt to refresh the resource loaders of the given module. * * @param name the name of the module to refresh */ void refreshResourceLoaders(String name); /** * Attempt to relink the given module. * * @param name the name of the module to relink */ void relink(String name); /** * Get the dependencies of the named module. * * @param name the module name * @return the module's dependencies */ List getDependencies(String name); /** * Get the resource loaders of the named module. * * @param name the module name * @return the module's resource loaders */ List getResourceLoaders(String name); /** * Get the complete description of this module. * * @param name the module name * @return the module description */ ModuleInfo getModuleDescription(String name); /** * Get a paths map for a given module. * * @param name the module name * @param exports {@code true} for the exported paths, {@code false} for all paths * @return the paths map information */ SortedMap> getModulePathsInfo(String name, boolean exports); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/ObjectProperties.java000066400000000000000000000107221257205723500316250ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.management; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; /** * A Hashtable variant which keeps property names in order, for use by MBean {@code ObjectName}s. * * @author David M. Lloyd */ public final class ObjectProperties extends Hashtable { private static final long serialVersionUID = -4691081844415343670L; private final Map realMap; public static Property property(String key, String value) { return new Property(key, value); } public static ObjectProperties properties(Property... properties) { return new ObjectProperties(properties); } public ObjectProperties(final int initialCapacity, final float loadFactor) { realMap = new LinkedHashMap(initialCapacity, loadFactor); } public ObjectProperties(final int initialCapacity) { realMap = new LinkedHashMap(initialCapacity); } public ObjectProperties() { realMap = new LinkedHashMap(); } public ObjectProperties(final Map t) { realMap = new LinkedHashMap(t); } public ObjectProperties(Property... properties) { realMap = new LinkedHashMap(properties.length); for (Property property : properties) { realMap.put(property.getKey(), property.getValue()); } } public int size() { return realMap.size(); } public boolean isEmpty() { return realMap.isEmpty(); } public Enumeration keys() { return Collections.enumeration(realMap.keySet()); } public Enumeration elements() { return Collections.enumeration(realMap.values()); } public boolean contains(final Object value) { return realMap.containsValue(value); } public boolean containsValue(final Object value) { return realMap.containsValue(value); } public boolean containsKey(final Object key) { return realMap.containsKey(key); } public String get(final Object key) { return realMap.get(key); } protected void rehash() { } public String put(final String key, final String value) { return realMap.put(key, value); } public String remove(final Object key) { return realMap.remove(key); } public void putAll(final Map t) { realMap.putAll(t); } public void clear() { realMap.clear(); } public Object clone() { return super.clone(); } public String toString() { return realMap.toString(); } public Set keySet() { return realMap.keySet(); } public Set> entrySet() { return realMap.entrySet(); } public Collection values() { return realMap.values(); } /** * A single property in a properties list. */ public static final class Property { private final String key; private final String value; public Property(final String key, final String value) { if (key == null) { throw new IllegalArgumentException("key is null"); } if (value == null) { throw new IllegalArgumentException("value is null"); } this.key = key; this.value = value; } public String getKey() { return key; } public String getValue() { return value; } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/ResourceLoaderInfo.java000066400000000000000000000031421257205723500320720ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.management; import java.beans.ConstructorProperties; import java.util.List; /** * Information about a resource loader. * * @author David M. Lloyd */ public final class ResourceLoaderInfo { private final String type; private final List paths; /** * Construct a new instance. * * @param type the type name * @param paths the paths list */ @ConstructorProperties({"type", "paths"}) public ResourceLoaderInfo(final String type, final List paths) { this.type = type; this.paths = paths; } /** * Get the type name. * * @return the type name */ public String getType() { return type; } /** * Get the paths list. * * @return the paths list */ public List getPaths() { return paths; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/management/package-info.java000066400000000000000000000014761257205723500306740ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ /** * Management interfaces for utilizing JBoss Modules via an MBean container. */ package org.jboss.modules.management;jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/package-info.java000066400000000000000000000017221257205723500265520ustar00rootroot00000000000000 /* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ /** * The primary JBoss Modules API. The key classes in this package are {@link Module}, {@link ModuleLoader}, * {@link ConcurrentClassLoader}, and {@link ModuleClassLoader}. These classes make up the backbone of the module * system. */ package org.jboss.modules;jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/000077500000000000000000000000001257205723500241355ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/PhantomReference.java000066400000000000000000000040041257205723500302230ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import java.lang.ref.ReferenceQueue; /** * A reapable phantom reference with an attachment. If a {@link Reaper} is given, then it will be used to asynchronously * clean up the referent. * * @param the reference value type * @param the attachment type * * @see java.lang.ref.PhantomReference * * @author David M. Lloyd */ public class PhantomReference extends java.lang.ref.PhantomReference implements Reference, Reapable { private final A attachment; private final Reaper reaper; public PhantomReference(final T referent, final A attachment, final ReferenceQueue q) { super(referent, q); this.attachment = attachment; reaper = null; } public PhantomReference(final T referent, final A attachment, final Reaper reaper) { super(referent, References.ReaperThread.REAPER_QUEUE); this.reaper = reaper; this.attachment = attachment; } public A getAttachment() { return attachment; } public Type getType() { return Type.PHANTOM; } public Reaper getReaper() { return reaper; } public String toString() { return "phantom reference to " + String.valueOf(get()); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/Reapable.java000066400000000000000000000021551257205723500265160ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; /** * A reference which is reapable (can be automatically collected). * * @param the reference type * @param the reference attachment type * * @apiviz.exclude * * @author David M. Lloyd */ interface Reapable { /** * Get the associated reaper. * * @return the reaper */ Reaper getReaper(); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/Reaper.java000066400000000000000000000021421257205723500262150ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; /** * A cleaner for a dead object. * * @param the reference type * @param the reference attachment type * * @author David M. Lloyd */ public interface Reaper { /** * Perform the cleanup action for a reference. * * @param reference the reference */ void reap(Reference reference); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/Reference.java000066400000000000000000000035441257205723500267040ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; /** * An enhanced reference type with a type-safe attachment. * * @param the reference value type * @param the attachment type * * @see java.lang.ref.Reference * * @author David M. Lloyd */ public interface Reference { /** * Get the value, or {@code null} if the reference has been cleared. * * @return the value */ T get(); /** * Get the attachment, if any. * * @return the attachment */ A getAttachment(); /** * Clear the reference. */ void clear(); /** * Get the type of the reference. * * @return the type */ Type getType(); /** * A reference type. * * @apiviz.exclude */ enum Type { /** * A strong reference. */ STRONG, /** * A weak reference. */ WEAK, /** * A phantom reference. */ PHANTOM, /** * A soft reference. */ SOFT, /** * A {@code null} reference. */ NULL, } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/References.java000066400000000000000000000154401257205723500270650ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import java.lang.ref.ReferenceQueue; /** * A set of utility methods for reference types. */ public final class References { @SuppressWarnings({ "RawUseOfParameterizedType" }) private static final Reference NULL = new Reference() { public Object get() { return null; } public Object getAttachment() { return null; } public void clear() { } public Type getType() { return Type.NULL; } public String toString() { return "NULL reference"; } }; private References() { } static final class ReaperThread extends Thread { static final ReferenceQueue REAPER_QUEUE = new ReferenceQueue(); static { final ReaperThread thr = new ReaperThread(); thr.setName("Reference Reaper"); thr.setDaemon(true); thr.start(); } public void run() { for (;;) try { final java.lang.ref.Reference ref = REAPER_QUEUE.remove(); if (ref instanceof Reapable) { reap((Reapable) ref); } } catch (InterruptedException ignored) { } catch (Throwable ignored) { } } @SuppressWarnings({ "unchecked" }) private static void reap(final Reapable reapable) { reapable.getReaper().reap((Reference) reapable); } } /** * Create a reference of a given type with the provided value and attachment. If the reference type is * {@link Reference.Type#STRONG} or {@link Reference.Type#NULL} then the reaper argument is ignored. If * the reference type is {@link Reference.Type#NULL} then the value and attachment arguments are ignored. * * @param type the reference type * @param value the reference value * @param attachment the attachment value * @param reaper the reaper to use, if any * @param the reference value type * @param the reference attachment type * @return the reference */ public static Reference create(Reference.Type type, T value, A attachment, Reaper reaper) { switch (type) { case STRONG: return new StrongReference(value, attachment); case WEAK: return new WeakReference(value, attachment, reaper); case PHANTOM: return new PhantomReference(value, attachment, reaper); case SOFT: return new SoftReference(value, attachment, reaper); case NULL: return getNullReference(); default: throw new IllegalStateException(); } } /** * Create a reference of a given type with the provided value and attachment. If the reference type is * {@link Reference.Type#STRONG} or {@link Reference.Type#NULL} then the reference queue argument is ignored. If * the reference type is {@link Reference.Type#NULL} then the value and attachment arguments are ignored. * * @param type the reference type * @param value the reference value * @param attachment the attachment value * @param referenceQueue the reference queue to use, if any * @param the reference value type * @param the reference attachment type * @return the reference */ public static Reference create(Reference.Type type, T value, A attachment, ReferenceQueue referenceQueue) { switch (type) { case STRONG: return new StrongReference(value, attachment); case WEAK: return new WeakReference(value, attachment, referenceQueue); case PHANTOM: return new PhantomReference(value, attachment, referenceQueue); case SOFT: return new SoftReference(value, attachment, referenceQueue); case NULL: return getNullReference(); default: throw new IllegalStateException(); } } /** * Create a reference of a given type with the provided value and attachment. If the reference type is * {@link Reference.Type#PHANTOM} then this method will throw an {@code IllegalArgumentException} because * such references are not constructable without a queue or reaper. If the reference type is * {@link Reference.Type#NULL} then the value and attachment arguments are ignored. * * @param type the reference type * @param value the reference value * @param attachment the attachment value * @param the reference value type * @param the reference attachment type * @return the reference * @throws IllegalArgumentException if the reference type is {@link Reference.Type#PHANTOM} */ public static Reference create(Reference.Type type, T value, A attachment) throws IllegalArgumentException { switch (type) { case STRONG: return new StrongReference(value, attachment); case WEAK: return new WeakReference(value, attachment); case PHANTOM: throw new IllegalArgumentException("Phantom reference may not be created without a queue or reaper"); case SOFT: return new SoftReference(value, attachment); case NULL: return getNullReference(); default: throw new IllegalStateException(); } } /** * Get a null reference. This reference type is always cleared and does not retain an attachment; as such * there is only one single instance of it. * * @param the reference value type * @param the attachment value type * @return the null reference */ @SuppressWarnings({ "unchecked" }) public static Reference getNullReference() { return (Reference) NULL; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/SoftReference.java000066400000000000000000000043361257205723500275400ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import java.lang.ref.ReferenceQueue; /** * A reapable soft reference with an attachment. If a {@link Reaper} is given, then it will be used to asynchronously * clean up the referent. * * @param the reference value type * @param the attachment type * * @see java.lang.ref.SoftReference * * @author David M. Lloyd */ public class SoftReference extends java.lang.ref.SoftReference implements Reference, Reapable { private final A attachment; private final Reaper reaper; public SoftReference(final T referent) { this(referent, null, (ReferenceQueue) null); } public SoftReference(final T referent, final A attachment) { this(referent, attachment, (ReferenceQueue) null); } public SoftReference(final T referent, final A attachment, final ReferenceQueue q) { super(referent, q); reaper = null; this.attachment = attachment; } public SoftReference(final T referent, final A attachment, final Reaper reaper) { super(referent, References.ReaperThread.REAPER_QUEUE); this.reaper = reaper; this.attachment = attachment; } public Reaper getReaper() { return reaper; } public A getAttachment() { return attachment; } public Type getType() { return Type.SOFT; } public String toString() { return "soft reference to " + String.valueOf(get()); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/StrongReference.java000066400000000000000000000032321257205723500300730ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; /** * A strong reference with an attachment. Since strong references are always reachable, a reaper may not be used. * * @param the reference value type * @param the attachment type * * @author David M. Lloyd */ public class StrongReference implements Reference { private volatile T value; private final A attachment; public StrongReference(final T value, final A attachment) { this.value = value; this.attachment = attachment; } public StrongReference(final T value) { this(value, null); } public T get() { return value; } public void clear() { value = null; } public A getAttachment() { return attachment; } public Type getType() { return Type.STRONG; } public String toString() { return "strong reference to " + String.valueOf(get()); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/WeakReference.java000066400000000000000000000043241257205723500275110ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import java.lang.ref.ReferenceQueue; /** * A reapable weak reference with an attachment. If a {@link Reaper} is given, then it will be used to asynchronously * clean up the referent. * * @param the reference value type * @param the attachment type * * @see java.lang.ref.WeakReference * * @author David M. Lloyd */ public class WeakReference extends java.lang.ref.WeakReference implements Reference, Reapable { private final A attachment; private final Reaper reaper; public WeakReference(final T referent) { this(referent, null, (Reaper) null); } public WeakReference(final T referent, final A attachment) { this(referent, attachment, (Reaper) null); } public WeakReference(final T referent, final A attachment, final ReferenceQueue q) { super(referent, q); this.attachment = attachment; reaper = null; } public WeakReference(final T referent, final A attachment, final Reaper reaper) { super(referent, References.ReaperThread.REAPER_QUEUE); this.attachment = attachment; this.reaper = reaper; } public A getAttachment() { return attachment; } public Type getType() { return Type.WEAK; } public Reaper getReaper() { return reaper; } public String toString() { return "weak reference to " + String.valueOf(get()); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ref/package-info.java000066400000000000000000000016501257205723500273260ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ /** * Classes which implement reference types which can be cleaned up automatically by a background thread. See * {@link Reference} and its subtypes, and {@link Reaper} for more information. */ package org.jboss.modules.ref;jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/000077500000000000000000000000001257205723500252305ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/FactoryPermissionCollection.java000066400000000000000000000054201257205723500335700ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.security; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.util.Enumeration; /** * A permission collection which lazily instantiates the permission objects on first use. Any * unavailable permission objects will not be granted to the resultant collection. * * @author David M. Lloyd */ public final class FactoryPermissionCollection extends PermissionCollection { private static final long serialVersionUID = -2524371701490830970L; private final PermissionFactory[] factories; private volatile Permissions assembled; /** * Construct a new instance. * * @param factories the factories to use to construct the permission collection */ public FactoryPermissionCollection(final PermissionFactory... factories) { this.factories = factories.clone(); } public void add(final Permission permission) { throw new SecurityException("Read-only permission collection"); } Permissions getAssembled() { if (assembled == null) { synchronized (this) { if (assembled == null) { final Permissions assembled = new Permissions(); for (PermissionFactory factory : factories) { if (factory != null) { final Permission permission = factory.construct(); if (permission != null) { assembled.add(permission); } } } assembled.setReadOnly(); this.assembled = assembled; } } } return assembled; } public boolean implies(final Permission permission) { return getAssembled().implies(permission); } public Enumeration elements() { return getAssembled().elements(); } Object writeReplace() { return getAssembled(); } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/ImmediatePermissionFactory.java000066400000000000000000000026501257205723500333750ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.security; import java.security.Permission; /** * A permission factory which simply holds a permission object. * * @author David M. Lloyd */ public final class ImmediatePermissionFactory implements PermissionFactory { private final Permission permission; /** * Construct a new instance. * * @param permission the permission to return */ public ImmediatePermissionFactory(final Permission permission) { if (permission == null) { throw new IllegalArgumentException("permission is null"); } this.permission = permission; } public Permission construct() { return permission; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/LoadedPermissionFactory.java000066400000000000000000000055521257205723500326730ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.security; import java.lang.reflect.Constructor; import java.security.Permission; /** * A permission factory which instantiates a permission with the given class name. * * @author David M. Lloyd */ public final class LoadedPermissionFactory implements PermissionFactory { private final ClassLoader classLoader; private final String className; private final String targetName; private final String permissionActions; private volatile Permission instance = UninitializedPermission.INSTANCE; /** * Construct a new instance. * * @param classLoader the class loader from which the permission should be loaded * @param className the name of the permission class * @param targetName the name to pass to the permission class constructor or {@code null} for none * @param permissionActions the action list to pass to the permission class constructor or {@code null} for none */ public LoadedPermissionFactory(final ClassLoader classLoader, final String className, final String targetName, final String permissionActions) { if (className == null) { throw new IllegalArgumentException("className is null"); } this.classLoader = classLoader; this.className = className; this.targetName = targetName; this.permissionActions = permissionActions; } public Permission construct() { if (instance != UninitializedPermission.INSTANCE) { return instance; } synchronized (this) { if (instance != UninitializedPermission.INSTANCE) { return instance; } try { final Class permissionClass = classLoader.loadClass(className).asSubclass(Permission.class); final Constructor constructor = permissionClass.getConstructor(String.class, String.class); return instance = constructor.newInstance(targetName, permissionActions); } catch (Throwable t) { instance = null; return null; } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/ModularPermissionFactory.java000066400000000000000000000072571257205723500331120ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.security; import java.lang.reflect.Constructor; import java.security.Permission; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoader; import org.jboss.modules._private.ModulesPrivateAccess; /** * A permission factory which instantiates a permission from a module. * * @author David M. Lloyd */ public final class ModularPermissionFactory implements PermissionFactory { private final ModuleLoader moduleLoader; private final ModuleIdentifier moduleIdentifier; private final String className; private final String targetName; private final String permissionActions; private volatile Permission instance = UninitializedPermission.INSTANCE; private static final ModulesPrivateAccess access = Module.getPrivateAccess(); /** * Construct a new instance. * * @param moduleLoader the module loader from which the module is to be loaded * @param moduleIdentifier the module identifier from which the permission is to be loaded * @param className the name of the permission class * @param targetName the name to pass to the permission class constructor or {@code null} for none * @param permissionActions the action list to pass to the permission class constructor or {@code null} for none */ public ModularPermissionFactory(final ModuleLoader moduleLoader, final ModuleIdentifier moduleIdentifier, final String className, final String targetName, final String permissionActions) { if (moduleLoader == null) { throw new IllegalArgumentException("moduleLoader is null"); } if (moduleIdentifier == null) { throw new IllegalArgumentException("moduleIdentifier is null"); } if (className == null) { throw new IllegalArgumentException("className is null"); } this.moduleLoader = moduleLoader; this.moduleIdentifier = moduleIdentifier; this.className = className; this.targetName = targetName; this.permissionActions = permissionActions; } public Permission construct() { if (instance != UninitializedPermission.INSTANCE) { return instance; } synchronized (this) { if (instance != UninitializedPermission.INSTANCE) { return instance; } try { final Module module = moduleLoader.loadModule(moduleIdentifier); final Class permissionClass = access.getClassLoaderOf(module).loadClass(className, true).asSubclass(Permission.class); final Constructor constructor = permissionClass.getConstructor(String.class, String.class); return instance = constructor.newInstance(targetName, permissionActions); } catch (Throwable t) { instance = null; return null; } } } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/PermissionFactory.java000066400000000000000000000021221257205723500315500ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.security; import java.security.Permission; /** * A factory for {@link Permission} objects. * * @author David M. Lloyd */ public interface PermissionFactory { /** * Construct a new instance of the permission. The instance may be cached. * * @return the permission */ Permission construct(); } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/security/UninitializedPermission.java000066400000000000000000000024711257205723500327600ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.security; import java.security.Permission; final class UninitializedPermission extends Permission { private static final long serialVersionUID = 468335190774708422L; static final UninitializedPermission INSTANCE = new UninitializedPermission(); private UninitializedPermission() { super(null); } public boolean implies(final Permission permission) { return false; } public boolean equals(final Object obj) { return false; } public int hashCode() { return 0; } public String getActions() { return null; } } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/xml/000077500000000000000000000000001257205723500241615ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/xml/MXParser.java000066400000000000000000004060141257205723500265320ustar00rootroot00000000000000/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ /* * Copyright (c) 2003 Extreme! Lab, Indiana University. All rights reserved. * * This software is open source. See the bottom of this file for the license. * * $Id: MXParser.java,v 1.52 2006/11/09 18:29:37 aslom Exp $ */ package org.jboss.modules.xml; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; //TODO best handling of interning issues // have isAllNewStringInterned ??? //TODO handling surrogate pairs: http://www.unicode.org/unicode/faq/utf_bom.html#6 //TODO review code for use of bufAbsoluteStart when keeping pos between next()/fillBuf() /** * Absolutely minimal implementation of XMLPULL V1 API * * @author Aleksander Slominski */ public class MXParser implements XmlPullParser { //NOTE: no interning of those strings --> by Java lang spec they MUST be already interned protected final static String XML_URI = "http://www.w3.org/XML/1998/namespace"; protected final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; protected final static String FEATURE_XML_ROUNDTRIP= //"http://xmlpull.org/v1/doc/features.html#xml-roundtrip"; "http://xmlpull.org/v1/doc/features.html#xml-roundtrip"; protected final static String FEATURE_NAMES_INTERNED = "http://xmlpull.org/v1/doc/features.html#names-interned"; protected final static String PROPERTY_XMLDECL_VERSION = "http://xmlpull.org/v1/doc/properties.html#xmldecl-version"; protected final static String PROPERTY_XMLDECL_STANDALONE = "http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone"; protected final static String PROPERTY_XMLDECL_CONTENT = "http://xmlpull.org/v1/doc/properties.html#xmldecl-content"; protected final static String PROPERTY_LOCATION = "http://xmlpull.org/v1/doc/properties.html#location"; /** * Implementation notice: * the is instance variable that controls if newString() is interning. *

NOTE: newStringIntern always returns interned strings * and newString MAY return interned String depending on this variable. *

NOTE: by default in this minimal implementation it is false! */ protected boolean allStringsInterned; protected void resetStringCache() { //System.out.println("resetStringCache() minimum called"); } protected String newString(char[] cbuf, int off, int len) { return new String(cbuf, off, len); } protected String newStringIntern(char[] cbuf, int off, int len) { return (new String(cbuf, off, len)).intern(); } private static final boolean TRACE_SIZING = false; // NOTE: features are not resettable and typically defaults to false ... protected boolean processNamespaces; protected boolean roundtripSupported; // global parser state protected String location; protected int lineNumber; protected int columnNumber; protected boolean seenRoot; protected boolean reachedEnd; protected int eventType; protected boolean emptyElementTag; // element stack protected int depth; protected char[] elRawName[]; protected int elRawNameEnd[]; protected int elRawNameLine[]; protected String elName[]; protected String elPrefix[]; protected String elUri[]; //protected String elValue[]; protected int elNamespaceCount[]; /** * Make sure that we have enough space to keep element stack if passed size. * It will always create one additional slot then current depth */ protected void ensureElementsCapacity() { final int elStackSize = elName != null ? elName.length : 0; if( (depth + 1) >= elStackSize) { // we add at least one extra slot ... final int newSize = (depth >= 7 ? 2 * depth : 8) + 2; // = lucky 7 + 1 //25 if(TRACE_SIZING) { System.err.println("TRACE_SIZING elStackSize "+elStackSize+" ==> "+newSize); } final boolean needsCopying = elStackSize > 0; String[] arr = null; // reuse arr local variable slot arr = new String[newSize]; if(needsCopying) System.arraycopy(elName, 0, arr, 0, elStackSize); elName = arr; arr = new String[newSize]; if(needsCopying) System.arraycopy(elPrefix, 0, arr, 0, elStackSize); elPrefix = arr; arr = new String[newSize]; if(needsCopying) System.arraycopy(elUri, 0, arr, 0, elStackSize); elUri = arr; int[] iarr = new int[newSize]; if(needsCopying) { System.arraycopy(elNamespaceCount, 0, iarr, 0, elStackSize); } else { // special initialization iarr[0] = 0; } elNamespaceCount = iarr; //TODO: avoid using element raw name ... iarr = new int[newSize]; if(needsCopying) { System.arraycopy(elRawNameEnd, 0, iarr, 0, elStackSize); } elRawNameEnd = iarr; iarr = new int[newSize]; if(needsCopying) { System.arraycopy(elRawNameLine, 0, iarr, 0, elStackSize); } elRawNameLine = iarr; final char[][] carr = new char[newSize][]; if(needsCopying) { System.arraycopy(elRawName, 0, carr, 0, elStackSize); } elRawName = carr; // arr = new String[newSize]; // if(needsCopying) System.arraycopy(elLocalName, 0, arr, 0, elStackSize); // elLocalName = arr; // arr = new String[newSize]; // if(needsCopying) System.arraycopy(elDefaultNs, 0, arr, 0, elStackSize); // elDefaultNs = arr; // int[] iarr = new int[newSize]; // if(needsCopying) System.arraycopy(elNsStackPos, 0, iarr, 0, elStackSize); // for (int i = elStackSize; i < iarr.length; i++) // { // iarr[i] = (i > 0) ? -1 : 0; // } // elNsStackPos = iarr; //assert depth < elName.length; } } // attribute stack protected int attributeCount; protected String attributeName[]; protected int attributeNameHash[]; //protected int attributeNameStart[]; //protected int attributeNameEnd[]; protected String attributePrefix[]; protected String attributeUri[]; protected String attributeValue[]; //protected int attributeValueStart[]; //protected int attributeValueEnd[]; /** * Make sure that in attributes temporary array is enough space. */ protected void ensureAttributesCapacity(int size) { final int attrPosSize = attributeName != null ? attributeName.length : 0; if(size >= attrPosSize) { final int newSize = size > 7 ? 2 * size : 8; // = lucky 7 + 1 //25 if(TRACE_SIZING) { System.err.println("TRACE_SIZING attrPosSize "+attrPosSize+" ==> "+newSize); } final boolean needsCopying = attrPosSize > 0; String[] arr = null; arr = new String[newSize]; if(needsCopying) System.arraycopy(attributeName, 0, arr, 0, attrPosSize); attributeName = arr; arr = new String[newSize]; if(needsCopying) System.arraycopy(attributePrefix, 0, arr, 0, attrPosSize); attributePrefix = arr; arr = new String[newSize]; if(needsCopying) System.arraycopy(attributeUri, 0, arr, 0, attrPosSize); attributeUri = arr; arr = new String[newSize]; if(needsCopying) System.arraycopy(attributeValue, 0, arr, 0, attrPosSize); attributeValue = arr; if( ! allStringsInterned ) { final int[] iarr = new int[newSize]; if(needsCopying) System.arraycopy(attributeNameHash, 0, iarr, 0, attrPosSize); attributeNameHash = iarr; } arr = null; // //assert attrUri.length > size } } // namespace stack protected int namespaceEnd; protected String namespacePrefix[]; protected int namespacePrefixHash[]; protected String namespaceUri[]; protected void ensureNamespacesCapacity(int size) { final int namespaceSize = namespacePrefix != null ? namespacePrefix.length : 0; if(size >= namespaceSize) { final int newSize = size > 7 ? 2 * size : 8; // = lucky 7 + 1 //25 if(TRACE_SIZING) { System.err.println("TRACE_SIZING namespaceSize "+namespaceSize+" ==> "+newSize); } final String[] newNamespacePrefix = new String[newSize]; final String[] newNamespaceUri = new String[newSize]; if(namespacePrefix != null) { System.arraycopy( namespacePrefix, 0, newNamespacePrefix, 0, namespaceEnd); System.arraycopy( namespaceUri, 0, newNamespaceUri, 0, namespaceEnd); } namespacePrefix = newNamespacePrefix; namespaceUri = newNamespaceUri; if( ! allStringsInterned ) { final int[] newNamespacePrefixHash = new int[newSize]; if(namespacePrefixHash != null) { System.arraycopy( namespacePrefixHash, 0, newNamespacePrefixHash, 0, namespaceEnd); } namespacePrefixHash = newNamespacePrefixHash; } //prefixesSize = newSize; // //assert nsPrefixes.length > size && nsPrefixes.length == newSize } } /** * simplistic implementation of hash function that has constant * time to compute - so it also means diminishing hash quality for long strings * but for XML parsing it should be good enough ... */ protected static final int fastHash( char ch[], int off, int len ) { if(len == 0) return 0; //assert len >0 int hash = ch[off]; // hash at beginning //try { hash = (hash << 7) + ch[ off + len - 1 ]; // hash at the end //} catch(ArrayIndexOutOfBoundsException aie) { // aie.printStackTrace(); //should never happen ... // throw new RuntimeException("this is violation of pre-condition"); //} if(len > 16) hash = (hash << 7) + ch[ off + (len / 4)]; // 1/4 from beginning if(len > 8) hash = (hash << 7) + ch[ off + (len / 2)]; // 1/2 of string size ... // notice that hash is at most done 3 times <<7 so shifted by 21 bits 8 bit value // so max result == 29 bits so it is quite just below 31 bits for long (2^32) ... //assert hash >= 0; return hash; } // entity replacement stack protected int entityEnd; protected String entityName[]; protected char[] entityNameBuf[]; protected String entityReplacement[]; protected char[] entityReplacementBuf[]; protected int entityNameHash[]; protected void ensureEntityCapacity() { final int entitySize = entityReplacementBuf != null ? entityReplacementBuf.length : 0; if(entityEnd >= entitySize) { final int newSize = entityEnd > 7 ? 2 * entityEnd : 8; // = lucky 7 + 1 //25 if(TRACE_SIZING) { System.err.println("TRACE_SIZING entitySize "+entitySize+" ==> "+newSize); } final String[] newEntityName = new String[newSize]; final char[] newEntityNameBuf[] = new char[newSize][]; final String[] newEntityReplacement = new String[newSize]; final char[] newEntityReplacementBuf[] = new char[newSize][]; if(entityName != null) { System.arraycopy(entityName, 0, newEntityName, 0, entityEnd); System.arraycopy(entityNameBuf, 0, newEntityNameBuf, 0, entityEnd); System.arraycopy(entityReplacement, 0, newEntityReplacement, 0, entityEnd); System.arraycopy(entityReplacementBuf, 0, newEntityReplacementBuf, 0, entityEnd); } entityName = newEntityName; entityNameBuf = newEntityNameBuf; entityReplacement = newEntityReplacement; entityReplacementBuf = newEntityReplacementBuf; if( ! allStringsInterned ) { final int[] newEntityNameHash = new int[newSize]; if(entityNameHash != null) { System.arraycopy(entityNameHash, 0, newEntityNameHash, 0, entityEnd); } entityNameHash = newEntityNameHash; } } } // input buffer management protected static final int READ_CHUNK_SIZE = 8*1024; //max data chars in one read() call protected Reader reader; protected String inputEncoding; protected InputStream inputStream; protected int bufLoadFactor = 95; // 99% //protected int bufHardLimit; // only matters when expanding protected char buf[] = new char[ Runtime.getRuntime().freeMemory() > 1000000L ? READ_CHUNK_SIZE : 256 ]; protected int bufSoftLimit = ( bufLoadFactor * buf.length ) /100; // desirable size of buffer protected boolean preventBufferCompaction; protected int bufAbsoluteStart; // this is buf protected int bufStart; protected int bufEnd; protected int pos; protected int posStart; protected int posEnd; protected char pc[] = new char[ Runtime.getRuntime().freeMemory() > 1000000L ? READ_CHUNK_SIZE : 64 ]; protected int pcStart; protected int pcEnd; // parsing state //protected boolean needsMore; //protected boolean seenMarkup; protected boolean usePC; protected boolean seenStartTag; protected boolean seenEndTag; protected boolean pastEndTag; protected boolean seenAmpersand; protected boolean seenMarkup; protected boolean seenDocdecl; // transient variable set during each call to next/Token() protected boolean tokenize; protected String text; protected String entityRefName; protected String xmlDeclVersion; protected Boolean xmlDeclStandalone; protected String xmlDeclContent; protected void reset() { //System.out.println("reset() called"); location = null; lineNumber = 1; columnNumber = 0; seenRoot = false; reachedEnd = false; eventType = START_DOCUMENT; emptyElementTag = false; depth = 0; attributeCount = 0; namespaceEnd = 0; entityEnd = 0; reader = null; inputEncoding = null; preventBufferCompaction = false; bufAbsoluteStart = 0; bufEnd = bufStart = 0; pos = posStart = posEnd = 0; pcEnd = pcStart = 0; usePC = false; seenStartTag = false; seenEndTag = false; pastEndTag = false; seenAmpersand = false; seenMarkup = false; seenDocdecl = false; xmlDeclVersion = null; xmlDeclStandalone = null; xmlDeclContent = null; resetStringCache(); } public MXParser() { } /** * Method setFeature * * @param name a String * @param state a boolean * * @throws XmlPullParserException * */ public void setFeature(String name, boolean state) throws XmlPullParserException { if(name == null) throw new IllegalArgumentException("feature name should not be null"); if(FEATURE_PROCESS_NAMESPACES.equals(name)) { if(eventType != START_DOCUMENT) throw new XmlPullParserException( "namespace processing feature can only be changed before parsing", this, null); processNamespaces = state; // } else if(FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) { // if(type != START_DOCUMENT) throw new XmlPullParserException( // "namespace reporting feature can only be changed before parsing", this, null); // reportNsAttribs = state; } else if(FEATURE_NAMES_INTERNED.equals(name)) { if(state != false) { throw new XmlPullParserException( "interning names in this implementation is not supported"); } } else if(FEATURE_PROCESS_DOCDECL.equals(name)) { if(state != false) { throw new XmlPullParserException( "processing DOCDECL is not supported"); } //} else if(REPORT_DOCDECL.equals(name)) { // paramNotifyDoctype = state; } else if(FEATURE_XML_ROUNDTRIP.equals(name)) { //if(state == false) { // throw new XmlPullParserException( // "roundtrip feature can not be switched off"); //} roundtripSupported = state; } else { throw new XmlPullParserException("unsupported feature "+name); } } /** Unknown properties are always returned as false */ public boolean getFeature(String name) { if(name == null) throw new IllegalArgumentException("feature name should not be null"); if(FEATURE_PROCESS_NAMESPACES.equals(name)) { return processNamespaces; // } else if(FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) { // return reportNsAttribs; } else if(FEATURE_NAMES_INTERNED.equals(name)) { return false; } else if(FEATURE_PROCESS_DOCDECL.equals(name)) { return false; //} else if(REPORT_DOCDECL.equals(name)) { // return paramNotifyDoctype; } else if(FEATURE_XML_ROUNDTRIP.equals(name)) { //return true; return roundtripSupported; } return false; } public void setProperty(String name, Object value) throws XmlPullParserException { if(PROPERTY_LOCATION.equals(name)) { location = (String) value; } else { throw new XmlPullParserException("unsupported property: '"+name+"'"); } } public Object getProperty(String name) { if(name == null) throw new IllegalArgumentException("property name should not be null"); if(PROPERTY_XMLDECL_VERSION.equals(name)) { return xmlDeclVersion; } else if(PROPERTY_XMLDECL_STANDALONE.equals(name)) { return xmlDeclStandalone; } else if(PROPERTY_XMLDECL_CONTENT.equals(name)) { return xmlDeclContent; } else if(PROPERTY_LOCATION.equals(name)) { return location; } return null; } public void setInput(Reader in) throws XmlPullParserException { reset(); reader = in; } public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException { if(inputStream == null) { throw new IllegalArgumentException("input stream can not be null"); } this.inputStream = inputStream; Reader reader; //if(inputEncoding != null) { try { if(inputEncoding != null) { reader = new InputStreamReader(inputStream, inputEncoding); } else { //by default use UTF-8 (InputStreamReader(inputStream)) would use OS default ... reader = new InputStreamReader(inputStream, "UTF-8"); } } catch (UnsupportedEncodingException une) { throw new XmlPullParserException( "could not create reader for encoding "+inputEncoding+" : "+une, this, une); } //} else { // reader = new InputStreamReader(inputStream); //} setInput(reader); //must be here as reest() was called in setInput() and has set this.inputEncoding to null ... this.inputEncoding = inputEncoding; } public String getInputEncoding() { return inputEncoding; } public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException { // throw new XmlPullParserException("not allowed"); //protected char[] entityReplacement[]; ensureEntityCapacity(); // this is to make sure that if interning works we will take advantage of it ... this.entityName[entityEnd] = newString(entityName.toCharArray(), 0, entityName.length()); entityNameBuf[entityEnd] = entityName.toCharArray(); entityReplacement[entityEnd] = replacementText; entityReplacementBuf[entityEnd] = replacementText.toCharArray(); if(!allStringsInterned) { entityNameHash[ entityEnd ] = fastHash(entityNameBuf[entityEnd], 0, entityNameBuf[entityEnd].length); } ++entityEnd; //TODO disallow < or & in entity replacement text (or ]]>???) // TOOD keepEntityNormalizedForAttributeValue cached as well ... } public int getNamespaceCount(int depth) throws XmlPullParserException { if(processNamespaces == false || depth == 0) { return 0; } //int maxDepth = eventType == END_TAG ? this.depth + 1 : this.depth; //if(depth < 0 || depth > maxDepth) throw new IllegalArgumentException( if(depth < 0 || depth > this.depth) throw new IllegalArgumentException( "allowed namespace depth 0.."+this.depth+" not "+depth); return elNamespaceCount[ depth ]; } public String getNamespacePrefix(int pos) throws XmlPullParserException { //int end = eventType == END_TAG ? elNamespaceCount[ depth + 1 ] : namespaceEnd; //if(pos < end) { if(pos < namespaceEnd) { return namespacePrefix[ pos ]; } else { throw new XmlPullParserException( "position "+pos+" exceeded number of available namespaces "+namespaceEnd); } } public String getNamespaceUri(int pos) throws XmlPullParserException { //int end = eventType == END_TAG ? elNamespaceCount[ depth + 1 ] : namespaceEnd; //if(pos < end) { if(pos < namespaceEnd) { return namespaceUri[ pos ]; } else { throw new XmlPullParserException( "position "+pos+" exceeded number of available namespaces "+namespaceEnd); } } public String getNamespace( String prefix ) //throws XmlPullParserException { //int count = namespaceCount[ depth ]; if(prefix != null) { for( int i = namespaceEnd -1; i >= 0; i--) { if( prefix.equals( namespacePrefix[ i ] ) ) { return namespaceUri[ i ]; } } if("xml".equals( prefix )) { return XML_URI; } else if("xmlns".equals( prefix )) { return XMLNS_URI; } } else { for( int i = namespaceEnd -1; i >= 0; i--) { if( namespacePrefix[ i ] == null) { //"") { //null ) { //TODO check FIXME Alek return namespaceUri[ i ]; } } } return null; } public int getDepth() { return depth; } private static int findFragment(int bufMinPos, char[] b, int start, int end) { //System.err.println("bufStart="+bufStart+" b="+printable(new String(b, start, end - start))+" start="+start+" end="+end); if(start < bufMinPos) { start = bufMinPos; if(start > end) start = end; return start; } if(end - start > 65) { start = end - 10; // try to find good location } int i = start + 1; while(--i > bufMinPos) { if((end - i) > 65) break; final char c = b[i]; if(c == '<' && (start - i) > 10) break; } return i; } /** * Return string describing current position of parsers as * text 'STATE [seen %s...] @line:column'. */ public String getPositionDescription () { String fragment = null; if(posStart <= pos) { final int start = findFragment(0, buf, posStart, pos); //System.err.println("start="+start); if(start < pos) { fragment = new String(buf, start, pos - start); } if(bufAbsoluteStart > 0 || start > 0) fragment = "..." + fragment; } // return " at line "+tokenizerPosRow // +" and column "+(tokenizerPosCol-1) // +(fragment != null ? " seen "+printable(fragment)+"..." : ""); return " "+TYPES[ eventType ] + (fragment != null ? " seen "+printable(fragment)+"..." : "") +" "+(location != null ? location : "") +"@"+getLineNumber()+":"+getColumnNumber(); } public int getLineNumber() { return lineNumber; } public int getColumnNumber() { return columnNumber; } public boolean isWhitespace() throws XmlPullParserException { if(eventType == TEXT || eventType == CDSECT) { if(usePC) { for (int i = pcStart; i = 0; i--) { // if( prefix.equals( namespacePrefix[ i ] ) ) { // return namespaceUri[ i ]; // } // } // } else { // for( int i = namespaceEnd -1; i >= 0; i--) { // if( namespacePrefix[ i ] == null ) { // return namespaceUri[ i ]; // } // } // // } // return ""; } public String getName() { if(eventType == START_TAG) { //return elName[ depth - 1 ] ; return elName[ depth ] ; } else if(eventType == END_TAG) { return elName[ depth ] ; } else if(eventType == ENTITY_REF) { if(entityRefName == null) { entityRefName = newString(buf, posStart, posEnd - posStart); } return entityRefName; } else { return null; } } public String getPrefix() { if(eventType == START_TAG) { //return elPrefix[ depth - 1 ] ; return elPrefix[ depth ] ; } else if(eventType == END_TAG) { return elPrefix[ depth ] ; } return null; // if(eventType != START_TAG && eventType != END_TAG) return null; // int maxDepth = eventType == END_TAG ? depth : depth - 1; // return elPrefix[ maxDepth ]; } public boolean isEmptyElementTag() throws XmlPullParserException { if(eventType != START_TAG) throw new XmlPullParserException( "parser must be on START_TAG to check for empty element", this, null); return emptyElementTag; } public int getAttributeCount() { if(eventType != START_TAG) return -1; return attributeCount; } public String getAttributeNamespace(int index) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"); if(processNamespaces == false) return NO_NAMESPACE; if(index < 0 || index >= attributeCount) throw new IndexOutOfBoundsException( "attribute position must be 0.."+(attributeCount-1)+" and not "+index); return attributeUri[ index ]; } public String getAttributeName(int index) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"); if(index < 0 || index >= attributeCount) throw new IndexOutOfBoundsException( "attribute position must be 0.."+(attributeCount-1)+" and not "+index); return attributeName[ index ]; } public String getAttributePrefix(int index) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"); if(processNamespaces == false) return null; if(index < 0 || index >= attributeCount) throw new IndexOutOfBoundsException( "attribute position must be 0.."+(attributeCount-1)+" and not "+index); return attributePrefix[ index ]; } public String getAttributeType(int index) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"); if(index < 0 || index >= attributeCount) throw new IndexOutOfBoundsException( "attribute position must be 0.."+(attributeCount-1)+" and not "+index); return "CDATA"; } public boolean isAttributeDefault(int index) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"); if(index < 0 || index >= attributeCount) throw new IndexOutOfBoundsException( "attribute position must be 0.."+(attributeCount-1)+" and not "+index); return false; } public String getAttributeValue(int index) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"); if(index < 0 || index >= attributeCount) throw new IndexOutOfBoundsException( "attribute position must be 0.."+(attributeCount-1)+" and not "+index); return attributeValue[ index ]; } public String getAttributeValue(String namespace, String name) { if(eventType != START_TAG) throw new IndexOutOfBoundsException( "only START_TAG can have attributes"+getPositionDescription()); if(name == null) { throw new IllegalArgumentException("attribute name can not be null"); } // TODO make check if namespace is interned!!! etc. for names!!! if(processNamespaces) { if(namespace == null) { namespace = ""; } for(int i = 0; i < attributeCount; ++i) { if((namespace == attributeUri[ i ] || namespace.equals(attributeUri[ i ]) ) //(namespace != null && namespace.equals(attributeUri[ i ])) // taking advantage of String.intern() && name.equals(attributeName[ i ]) ) { return attributeValue[i]; } } } else { if(namespace != null && namespace.length() == 0) { namespace = null; } if(namespace != null) throw new IllegalArgumentException( "when namespaces processing is disabled attribute namespace must be null"); for(int i = 0; i < attributeCount; ++i) { if(name.equals(attributeName[i])) { return attributeValue[i]; } } } return null; } public int getEventType() { return eventType; } public void require(int type, String namespace, String name) throws XmlPullParserException, IOException { if(processNamespaces == false && namespace != null) { throw new XmlPullParserException( "processing namespaces must be enabled on parser (or factory)"+ " to have possible namespaces declared on elements" +(" (position:"+ getPositionDescription())+")"); } if (type != getEventType() || (namespace != null && !namespace.equals (getNamespace())) || (name != null && !name.equals (getName ())) ) { throw new XmlPullParserException ( "expected event "+TYPES[ type ] +(name != null ? " with name '"+name+"'" : "") +(namespace != null && name != null ? " and" : "") +(namespace != null ? " with namespace '"+namespace+"'" : "") +" but got" +(type != getEventType() ? " "+TYPES[ getEventType() ] : "") +(name != null && getName() != null && !name.equals (getName ()) ? " name '"+getName()+"'" : "") +(namespace != null && name != null && getName() != null && !name.equals (getName ()) && getNamespace() != null && !namespace.equals (getNamespace()) ? " and" : "") +(namespace != null && getNamespace() != null && !namespace.equals (getNamespace()) ? " namespace '"+getNamespace()+"'" : "") +(" (position:"+ getPositionDescription())+")"); } } /** * Skip sub tree that is currently parser positioned on. *
NOTE: parser must be on START_TAG and when function returns * parser will be positioned on corresponding END_TAG */ public void skipSubTree() throws XmlPullParserException, IOException { require(START_TAG, null, null); int level = 1; while(level > 0) { int eventType = next(); if(eventType == END_TAG) { --level; } else if(eventType == START_TAG) { ++level; } } } // public String readText() throws XmlPullParserException, IOException // { // if (getEventType() != TEXT) return ""; // String result = getText(); // next(); // return result; // } public String nextText() throws XmlPullParserException, IOException { // String result = null; // boolean onStartTag = false; // if(eventType == START_TAG) { // onStartTag = true; // next(); // } // if(eventType == TEXT) { // result = getText(); // next(); // } else if(onStartTag && eventType == END_TAG) { // result = ""; // } else { // throw new XmlPullParserException( // "parser must be on START_TAG or TEXT to read text", this, null); // } // if(eventType != END_TAG) { // throw new XmlPullParserException( // "event TEXT it must be immediately followed by END_TAG", this, null); // } // return result; if(getEventType() != START_TAG) { throw new XmlPullParserException( "parser must be on START_TAG to read next text", this, null); } int eventType = next(); if(eventType == TEXT) { final String result = getText(); eventType = next(); if(eventType != END_TAG) { throw new XmlPullParserException( "TEXT must be immediately followed by END_TAG and not " +TYPES[ getEventType() ], this, null); } return result; } else if(eventType == END_TAG) { return ""; } else { throw new XmlPullParserException( "parser must be on START_TAG or TEXT to read text", this, null); } } public int nextTag() throws XmlPullParserException, IOException { next(); if(eventType == TEXT && isWhitespace()) { // skip whitespace next(); } if (eventType != START_TAG && eventType != END_TAG) { throw new XmlPullParserException("expected START_TAG or END_TAG not " +TYPES[ getEventType() ], this, null); } return eventType; } public int next() throws XmlPullParserException, IOException { tokenize = false; return nextImpl(); } public int nextToken() throws XmlPullParserException, IOException { tokenize = true; return nextImpl(); } protected int nextImpl() throws XmlPullParserException, IOException { text = null; pcEnd = pcStart = 0; usePC = false; bufStart = posEnd; if(pastEndTag) { pastEndTag = false; --depth; namespaceEnd = elNamespaceCount[ depth ]; // less namespaces available } if(emptyElementTag) { emptyElementTag = false; pastEndTag = true; return eventType = END_TAG; } // [1] document ::= prolog element Misc* if(depth > 0) { if(seenStartTag) { seenStartTag = false; return eventType = parseStartTag(); } if(seenEndTag) { seenEndTag = false; return eventType = parseEndTag(); } // ASSUMPTION: we are _on_ first character of content or markup!!!! // [43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)* char ch; if(seenMarkup) { // we have read ahead ... seenMarkup = false; ch = '<'; } else if(seenAmpersand) { seenAmpersand = false; ch = '&'; } else { ch = more(); } posStart = pos - 1; // VERY IMPORTANT: this is correct start of event!!! // when true there is some potential event TEXT to return - keep gathering boolean hadCharData = false; // when true TEXT data is not continual (like ) and requires PC merging boolean needsMerging = false; MAIN_LOOP: while(true) { // work on MARKUP if(ch == '<') { if(hadCharData) { //posEnd = pos - 1; if(tokenize) { seenMarkup = true; return eventType = TEXT; } } ch = more(); if(ch == '/') { if(!tokenize && hadCharData) { seenEndTag = true; //posEnd = pos - 2; return eventType = TEXT; } return eventType = parseEndTag(); } else if(ch == '!') { ch = more(); if(ch == '-') { // note: if(tokenize == false) posStart/End is NOT changed!!!! parseComment(); if(tokenize) return eventType = COMMENT; if( !usePC && hadCharData ) { needsMerging = true; } else { posStart = pos; //completely ignore comment } } else if(ch == '[') { //posEnd = pos - 3; // must remember previous posStart/End as it merges with content of CDATA //int oldStart = posStart + bufAbsoluteStart; //int oldEnd = posEnd + bufAbsoluteStart; parseCDSect(hadCharData); if(tokenize) return eventType = CDSECT; final int cdStart = posStart; final int cdEnd = posEnd; final int cdLen = cdEnd - cdStart; if(cdLen > 0) { // was there anything inside CDATA section? hadCharData = true; if(!usePC) { needsMerging = true; } } // posStart = oldStart; // posEnd = oldEnd; // if(cdLen > 0) { // was there anything inside CDATA section? // if(hadCharData) { // // do merging if there was anything in CDSect!!!! // // if(!usePC) { // // // posEnd is correct already!!! // // if(posEnd > posStart) { // // joinPC(); // // } else { // // usePC = true; // // pcStart = pcEnd = 0; // // } // // } // // if(pcEnd + cdLen >= pc.length) ensurePC(pcEnd + cdLen); // // // copy [cdStart..cdEnd) into PC // // System.arraycopy(buf, cdStart, pc, pcEnd, cdLen); // // pcEnd += cdLen; // if(!usePC) { // needsMerging = true; // posStart = cdStart; // posEnd = cdEnd; // } // } else { // if(!usePC) { // needsMerging = true; // posStart = cdStart; // posEnd = cdEnd; // hadCharData = true; // } // } // //hadCharData = true; // } else { // if( !usePC && hadCharData ) { // needsMerging = true; // } // } } else { throw new XmlPullParserException( "unexpected character in markup "+printable(ch), this, null); } } else if(ch == '?') { parsePI(); if(tokenize) return eventType = PROCESSING_INSTRUCTION; if( !usePC && hadCharData ) { needsMerging = true; } else { posStart = pos; //completely ignore PI } } else if( isNameStartChar(ch) ) { if(!tokenize && hadCharData) { seenStartTag = true; //posEnd = pos - 2; return eventType = TEXT; } return eventType = parseStartTag(); } else { throw new XmlPullParserException( "unexpected character in markup "+printable(ch), this, null); } // do content compaction if it makes sense!!!! } else if(ch == '&') { // work on ENTITTY //posEnd = pos - 1; if(tokenize && hadCharData) { seenAmpersand = true; return eventType = TEXT; } final int oldStart = posStart + bufAbsoluteStart; final int oldEnd = posEnd + bufAbsoluteStart; final char[] resolvedEntity = parseEntityRef(); if(tokenize) return eventType = ENTITY_REF; // check if replacement text can be resolved !!! if(resolvedEntity == null) { if(entityRefName == null) { entityRefName = newString(buf, posStart, posEnd - posStart); } throw new XmlPullParserException( "could not resolve entity named '"+printable(entityRefName)+"'", this, null); } //int entStart = posStart; //int entEnd = posEnd; posStart = oldStart - bufAbsoluteStart; posEnd = oldEnd - bufAbsoluteStart; if(!usePC) { if(hadCharData) { joinPC(); // posEnd is already set correctly!!! needsMerging = false; } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; // write into PC replacement text - do merge for replacement text!!!! for (int i = 0; i < resolvedEntity.length; i++) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = resolvedEntity[ i ]; } hadCharData = true; //assert needsMerging == false; } else { if(needsMerging) { //assert usePC == false; joinPC(); // posEnd is already set correctly!!! //posStart = pos - 1; needsMerging = false; } //no MARKUP not ENTITIES so work on character data ... // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*) hadCharData = true; boolean normalizedCR = false; final boolean normalizeInput = tokenize == false || roundtripSupported == false; // use loop locality here!!!! boolean seenBracket = false; boolean seenBracketBracket = false; do { // check that ]]> does not show in if(ch == ']') { if(seenBracket) { seenBracketBracket = true; } else { seenBracket = true; } } else if(seenBracketBracket && ch == '>') { throw new XmlPullParserException( "characters ]]> are not allowed in content", this, null); } else { if(seenBracket) { seenBracketBracket = seenBracket = false; } // assert seenTwoBrackets == seenBracket == false; } if(normalizeInput) { // deal with normalization issues ... if(ch == '\r') { normalizedCR = true; posEnd = pos -1; // posEnd is already is set if(!usePC) { if(posEnd > posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { // if(!usePC) { joinPC(); } else { if(pcEnd >= pc.length) ensurePC(); } if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } ch = more(); } while(ch != '<' && ch != '&'); posEnd = pos - 1; continue MAIN_LOOP; // skip ch = more() from below - we are alreayd ahead ... } ch = more(); } // endless while(true) } else { if(seenRoot) { return parseEpilog(); } else { return parseProlog(); } } } protected int parseProlog() throws XmlPullParserException, IOException { // [2] prolog: ::= XMLDecl? Misc* (doctypedecl Misc*)? and look for [39] element char ch; if(seenMarkup) { ch = buf[ pos - 1 ]; } else { ch = more(); } if(eventType == START_DOCUMENT) { // bootstrap parsing with getting first character input! // deal with BOM // detect BOM and drop it (Unicode int Order Mark) if(ch == '\uFFFE') { throw new XmlPullParserException( "first character in input was UNICODE noncharacter (0xFFFE)"+ "- input requires int swapping", this, null); } if(ch == '\uFEFF') { // skipping UNICODE int Order Mark (so called BOM) ch = more(); } } seenMarkup = false; boolean gotS = false; posStart = pos - 1; final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; boolean normalizedCR = false; while(true) { // deal with Misc // [27] Misc ::= Comment | PI | S // deal with docdecl --> mark it! // else parseStartTag seen <[^/] if(ch == '<') { if(gotS && tokenize) { posEnd = pos - 1; seenMarkup = true; return eventType = IGNORABLE_WHITESPACE; } ch = more(); if(ch == '?') { // check if it is 'xml' // deal with XMLDecl if(parsePI()) { // make sure to skip XMLDecl if(tokenize) { return eventType = PROCESSING_INSTRUCTION; } } else { // skip over - continue tokenizing posStart = pos; gotS = false; } } else if(ch == '!') { ch = more(); if(ch == 'D') { if(seenDocdecl) { throw new XmlPullParserException( "only one docdecl allowed in XML document", this, null); } seenDocdecl = true; parseDocdecl(); if(tokenize) return eventType = DOCDECL; } else if(ch == '-') { parseComment(); if(tokenize) return eventType = COMMENT; } else { throw new XmlPullParserException( "unexpected markup posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } } else { throw new XmlPullParserException( "only whitespace content allowed before start tag and not "+printable(ch), this, null); } ch = more(); } } protected int parseEpilog() throws XmlPullParserException, IOException { if(eventType == END_DOCUMENT) { throw new XmlPullParserException("already reached end of XML input", this, null); } if(reachedEnd) { return eventType = END_DOCUMENT; } boolean gotS = false; final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; boolean normalizedCR = false; try { // epilog: Misc* char ch; if(seenMarkup) { ch = buf[ pos - 1 ]; } else { ch = more(); } seenMarkup = false; posStart = pos - 1; if(!reachedEnd) { while(true) { // deal with Misc // [27] Misc ::= Comment | PI | S if(ch == '<') { if(gotS && tokenize) { posEnd = pos - 1; seenMarkup = true; return eventType = IGNORABLE_WHITESPACE; } ch = more(); if(reachedEnd) { break; } if(ch == '?') { // check if it is 'xml' // deal with XMLDecl parsePI(); if(tokenize) return eventType = PROCESSING_INSTRUCTION; } else if(ch == '!') { ch = more(); if(reachedEnd) { break; } if(ch == 'D') { parseDocdecl(); //FIXME if(tokenize) return eventType = DOCDECL; } else if(ch == '-') { parseComment(); if(tokenize) return eventType = COMMENT; } else { throw new XmlPullParserException( "unexpected markup posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } } else { throw new XmlPullParserException( "in epilog non whitespace content is not allowed but got "+printable(ch), this, null); } ch = more(); if(reachedEnd) { break; } } } // throw Exception("unexpected content in epilog // catch EOFException return END_DOCUEMENT //try { } catch(EOFException ex) { reachedEnd = true; } if(reachedEnd) { if(tokenize && gotS) { posEnd = pos; // well - this is LAST available character pos return eventType = IGNORABLE_WHITESPACE; } return eventType = END_DOCUMENT; } else { throw new XmlPullParserException("internal error in parseEpilog"); } } public int parseEndTag() throws XmlPullParserException, IOException { //ASSUMPTION ch is past "' char ch = more(); if(!isNameStartChar(ch)) { throw new XmlPullParserException( "expected name start and not "+printable(ch), this, null); } posStart = pos - 3; final int nameStart = pos - 1 + bufAbsoluteStart; do { ch = more(); } while(isNameChar(ch)); // now we go one level down -- do checks //--depth; //FIXME // check that end tag name is the same as start tag //String name = new String(buf, nameStart - bufAbsoluteStart, // (pos - 1) - (nameStart - bufAbsoluteStart)); //int last = pos - 1; int off = nameStart - bufAbsoluteStart; //final int len = last - off; final int len = (pos - 1) - off; final char[] cbuf = elRawName[depth]; if(elRawNameEnd[depth] != len) { // construct strings for exception final String startname = new String(cbuf, 0, elRawNameEnd[depth]); final String endname = new String(buf, off, len); throw new XmlPullParserException( "end tag name must match start tag name <"+startname+">" +" from line "+elRawNameLine[depth], this, null); } for (int i = 0; i < len; i++) { if(buf[off++] != cbuf[i]) { // construct strings for exception final String startname = new String(cbuf, 0, len); final String endname = new String(buf, off - i - 1, len); throw new XmlPullParserException( "end tag name must be the same as start tag <"+startname+">" +" from line "+elRawNameLine[depth], this, null); } } while(isS(ch)) { ch = more(); } // skip additional white spaces if(ch != '>') { throw new XmlPullParserException( "expected > to finish end tag not "+printable(ch) +" from line "+elRawNameLine[depth], this, null); } //namespaceEnd = elNamespaceCount[ depth ]; //FIXME posEnd = pos; pastEndTag = true; return eventType = END_TAG; } public int parseStartTag() throws XmlPullParserException, IOException { //ASSUMPTION ch is past ' // [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' ++depth; //FIXME posStart = pos - 2; emptyElementTag = false; attributeCount = 0; // retrieve name final int nameStart = pos - 1 + bufAbsoluteStart; int colonPos = -1; char ch = buf[ pos - 1]; if(ch == ':' && processNamespaces) throw new XmlPullParserException( "when namespaces processing enabled colon can not be at element name start", this, null); while(true) { ch = more(); if(!isNameChar(ch)) break; if(ch == ':' && processNamespaces) { if(colonPos != -1) throw new XmlPullParserException( "only one colon is allowed in name of element when namespaces are enabled", this, null); colonPos = pos - 1 + bufAbsoluteStart; } } // retrieve name ensureElementsCapacity(); //TODO check for efficient interning and then use elRawNameInterned!!!! int elLen = (pos - 1) - (nameStart - bufAbsoluteStart); if(elRawName[ depth ] == null || elRawName[ depth ].length < elLen) { elRawName[ depth ] = new char[ 2 * elLen ]; } System.arraycopy(buf, nameStart - bufAbsoluteStart, elRawName[ depth ], 0, elLen); elRawNameEnd[ depth ] = elLen; elRawNameLine[ depth ] = lineNumber; String name = null; // work on prefixes and namespace URI String prefix = null; if(processNamespaces) { if(colonPos != -1) { prefix = elPrefix[ depth ] = newString(buf, nameStart - bufAbsoluteStart, colonPos - nameStart); name = elName[ depth ] = newString(buf, colonPos + 1 - bufAbsoluteStart, //(pos -1) - (colonPos + 1)); pos - 2 - (colonPos - bufAbsoluteStart)); } else { prefix = elPrefix[ depth ] = null; name = elName[ depth ] = newString(buf, nameStart - bufAbsoluteStart, elLen); } } else { name = elName[ depth ] = newString(buf, nameStart - bufAbsoluteStart, elLen); } while(true) { while(isS(ch)) { ch = more(); } // skip additional white spaces if(ch == '>') { break; } else if(ch == '/') { if(emptyElementTag) throw new XmlPullParserException( "repeated / in tag declaration", this, null); emptyElementTag = true; ch = more(); if(ch != '>') throw new XmlPullParserException( "expected > to end empty tag not "+printable(ch), this, null); break; } else if(isNameStartChar(ch)) { ch = parseAttribute(); ch = more(); continue; } else { throw new XmlPullParserException( "start tag unexpected character "+printable(ch), this, null); } //ch = more(); // skip space } // now when namespaces were declared we can resolve them if(processNamespaces) { String uri = getNamespace(prefix); if(uri == null) { if(prefix == null) { // no prefix and no uri => use default namespace uri = NO_NAMESPACE; } else { throw new XmlPullParserException( "could not determine namespace bound to element prefix "+prefix, this, null); } } elUri[ depth ] = uri; //String uri = getNamespace(prefix); //if(uri == null && prefix == null) { // no prefix and no uri => use default namespace // uri = ""; //} // resolve attribute namespaces for (int i = 0; i < attributeCount; i++) { final String attrPrefix = attributePrefix[ i ]; if(attrPrefix != null) { final String attrUri = getNamespace(attrPrefix); if(attrUri == null) { throw new XmlPullParserException( "could not determine namespace bound to attribute prefix "+attrPrefix, this, null); } attributeUri[ i ] = attrUri; } else { attributeUri[ i ] = NO_NAMESPACE; } } //TODO //[ WFC: Unique Att Spec ] // check attribute uniqueness constraint for attributes that has namespace!!! for (int i = 1; i < attributeCount; i++) { for (int j = 0; j < i; j++) { if( attributeUri[j] == attributeUri[i] && (allStringsInterned && attributeName[j].equals(attributeName[i]) || (!allStringsInterned && attributeNameHash[ j ] == attributeNameHash[ i ] && attributeName[j].equals(attributeName[i])) ) ) { // prepare data for nice error message? String attr1 = attributeName[j]; if(attributeUri[j] != null) attr1 = attributeUri[j]+":"+attr1; String attr2 = attributeName[i]; if(attributeUri[i] != null) attr2 = attributeUri[i]+":"+attr2; throw new XmlPullParserException( "duplicated attributes "+attr1+" and "+attr2, this, null); } } } } else { // ! processNamespaces //[ WFC: Unique Att Spec ] // check raw attribute uniqueness constraint!!! for (int i = 1; i < attributeCount; i++) { for (int j = 0; j < i; j++) { if((allStringsInterned && attributeName[j].equals(attributeName[i]) || (!allStringsInterned && attributeNameHash[ j ] == attributeNameHash[ i ] && attributeName[j].equals(attributeName[i])) ) ) { // prepare data for nice error message? final String attr1 = attributeName[j]; final String attr2 = attributeName[i]; throw new XmlPullParserException( "duplicated attributes "+attr1+" and "+attr2, this, null); } } } } elNamespaceCount[ depth ] = namespaceEnd; posEnd = pos; return eventType = START_TAG; } protected char parseAttribute() throws XmlPullParserException, IOException { // parse attribute // [41] Attribute ::= Name Eq AttValue // [WFC: No External Entity References] // [WFC: No < in Attribute Values] final int prevPosStart = posStart + bufAbsoluteStart; final int nameStart = pos - 1 + bufAbsoluteStart; int colonPos = -1; char ch = buf[ pos - 1 ]; if(ch == ':' && processNamespaces) throw new XmlPullParserException( "when namespaces processing enabled colon can not be at attribute name start", this, null); boolean startsWithXmlns = processNamespaces && ch == 'x'; int xmlnsPos = 0; ch = more(); while(isNameChar(ch)) { if(processNamespaces) { if(startsWithXmlns && xmlnsPos < 5) { ++xmlnsPos; if(xmlnsPos == 1) { if(ch != 'm') startsWithXmlns = false; } else if(xmlnsPos == 2) { if(ch != 'l') startsWithXmlns = false; } else if(xmlnsPos == 3) { if(ch != 'n') startsWithXmlns = false; } else if(xmlnsPos == 4) { if(ch != 's') startsWithXmlns = false; } else if(xmlnsPos == 5) { if(ch != ':') throw new XmlPullParserException( "after xmlns in attribute name must be colon" +"when namespaces are enabled", this, null); //colonPos = pos - 1 + bufAbsoluteStart; } } if(ch == ':') { if(colonPos != -1) throw new XmlPullParserException( "only one colon is allowed in attribute name" +" when namespaces are enabled", this, null); colonPos = pos - 1 + bufAbsoluteStart; } } ch = more(); } ensureAttributesCapacity(attributeCount); // --- start processing attributes String name = null; String prefix = null; // work on prefixes and namespace URI if(processNamespaces) { if(xmlnsPos < 4) startsWithXmlns = false; if(startsWithXmlns) { if(colonPos != -1) { //prefix = attributePrefix[ attributeCount ] = null; final int nameLen = pos - 2 - (colonPos - bufAbsoluteStart); if(nameLen == 0) { throw new XmlPullParserException( "namespace prefix is required after xmlns: " +" when namespaces are enabled", this, null); } name = //attributeName[ attributeCount ] = newString(buf, colonPos - bufAbsoluteStart + 1, nameLen); //pos - 1 - (colonPos + 1 - bufAbsoluteStart) } } else { if(colonPos != -1) { int prefixLen = colonPos - nameStart; prefix = attributePrefix[ attributeCount ] = newString(buf, nameStart - bufAbsoluteStart,prefixLen); //colonPos - (nameStart - bufAbsoluteStart)); int nameLen = pos - 2 - (colonPos - bufAbsoluteStart); name = attributeName[ attributeCount ] = newString(buf, colonPos - bufAbsoluteStart + 1, nameLen); //pos - 1 - (colonPos + 1 - bufAbsoluteStart)); //name.substring(0, colonPos-nameStart); } else { prefix = attributePrefix[ attributeCount ] = null; name = attributeName[ attributeCount ] = newString(buf, nameStart - bufAbsoluteStart, pos - 1 - (nameStart - bufAbsoluteStart)); } if(!allStringsInterned) { attributeNameHash[ attributeCount ] = name.hashCode(); } } } else { // retrieve name name = attributeName[ attributeCount ] = newString(buf, nameStart - bufAbsoluteStart, pos - 1 - (nameStart - bufAbsoluteStart)); ////assert name != null; if(!allStringsInterned) { attributeNameHash[ attributeCount ] = name.hashCode(); } } // [25] Eq ::= S? '=' S? while(isS(ch)) { ch = more(); } // skip additional spaces if(ch != '=') throw new XmlPullParserException( "expected = after attribute name", this, null); ch = more(); while(isS(ch)) { ch = more(); } // skip additional spaces // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' // | "'" ([^<&'] | Reference)* "'" final char delimit = ch; if(delimit != '"' && delimit != '\'') throw new XmlPullParserException( "attribute value must start with quotation or apostrophe not " +printable(delimit), this, null); // parse until delimit or < and resolve Reference //[67] Reference ::= EntityRef | CharRef //int valueStart = pos + bufAbsoluteStart; boolean normalizedCR = false; usePC = false; pcStart = pcEnd; posStart = pos; while(true) { ch = more(); if(ch == delimit) { break; } if(ch == '<') { throw new XmlPullParserException( "markup not allowed inside attribute value - illegal < ", this, null); } if(ch == '&') { // extractEntityRef posEnd = pos - 1; if(!usePC) { final boolean hadCharData = posEnd > posStart; if(hadCharData) { // posEnd is already set correctly!!! joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; final char[] resolvedEntity = parseEntityRef(); // check if replacement text can be resolved !!! if(resolvedEntity == null) { if(entityRefName == null) { entityRefName = newString(buf, posStart, posEnd - posStart); } throw new XmlPullParserException( "could not resolve entity named '"+printable(entityRefName)+"'", this, null); } // write into PC replacement text - do merge for replacement text!!!! for (int i = 0; i < resolvedEntity.length; i++) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = resolvedEntity[ i ]; } } else if(ch == '\t' || ch == '\n' || ch == '\r') { // do attribute value normalization // as described in http://www.w3.org/TR/REC-xml#AVNormalize // TODO add test for it form spec ... // handle EOL normalization ... if(!usePC) { posEnd = pos - 1; if(posEnd > posStart) { joinPC(); } else { usePC = true; pcEnd = pcStart = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); if(ch != '\n' || !normalizedCR) { pc[pcEnd++] = ' '; //'\n'; } } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } } normalizedCR = ch == '\r'; } if(processNamespaces && startsWithXmlns) { String ns = null; if(!usePC) { ns = newStringIntern(buf, posStart, pos - 1 - posStart); } else { ns = newStringIntern(pc, pcStart, pcEnd - pcStart); } ensureNamespacesCapacity(namespaceEnd); int prefixHash = -1; if(colonPos != -1) { if(ns.length() == 0) { throw new XmlPullParserException( "non-default namespace can not be declared to be empty string", this, null); } // declare new namespace namespacePrefix[ namespaceEnd ] = name; if(!allStringsInterned) { prefixHash = namespacePrefixHash[ namespaceEnd ] = name.hashCode(); } } else { // declare new default namespace ... namespacePrefix[ namespaceEnd ] = null; //""; //null; //TODO check FIXME Alek if(!allStringsInterned) { prefixHash = namespacePrefixHash[ namespaceEnd ] = -1; } } namespaceUri[ namespaceEnd ] = ns; // detect duplicate namespace declarations!!! final int startNs = elNamespaceCount[ depth - 1 ]; for (int i = namespaceEnd - 1; i >= startNs; --i) { if(((allStringsInterned || name == null) && namespacePrefix[ i ] == name) || (!allStringsInterned && name != null && namespacePrefixHash[ i ] == prefixHash && name.equals(namespacePrefix[ i ]) )) { final String s = name == null ? "default" : "'"+name+"'"; throw new XmlPullParserException( "duplicated namespace declaration for "+s+" prefix", this, null); } } ++namespaceEnd; } else { if(!usePC) { attributeValue[ attributeCount ] = new String(buf, posStart, pos - 1 - posStart); } else { attributeValue[ attributeCount ] = new String(pc, pcStart, pcEnd - pcStart); } ++attributeCount; } posStart = prevPosStart - bufAbsoluteStart; return ch; } protected char[] charRefOneCharBuf = new char[1]; protected char[] parseEntityRef() throws XmlPullParserException, IOException { // entity reference http://www.w3.org/TR/2000/REC-xml-20001006#NT-Reference // [67] Reference ::= EntityRef | CharRef // ASSUMPTION just after & entityRefName = null; posStart = pos; char ch = more(); if(ch == '#') { // parse character reference char charRef = 0; ch = more(); if(ch == 'x') { //encoded in hex while(true) { ch = more(); if(ch >= '0' && ch <= '9') { charRef = (char)(charRef * 16 + (ch - '0')); } else if(ch >= 'a' && ch <= 'f') { charRef = (char)(charRef * 16 + (ch - ('a' - 10))); } else if(ch >= 'A' && ch <= 'F') { charRef = (char)(charRef * 16 + (ch - ('A' - 10))); } else if(ch == ';') { break; } else { throw new XmlPullParserException( "character reference (with hex value) may not contain " +printable(ch), this, null); } } } else { // encoded in decimal while(true) { if(ch >= '0' && ch <= '9') { charRef = (char)(charRef * 10 + (ch - '0')); } else if(ch == ';') { break; } else { throw new XmlPullParserException( "character reference (with decimal value) may not contain " +printable(ch), this, null); } ch = more(); } } posEnd = pos - 1; charRefOneCharBuf[0] = charRef; if(tokenize) { text = newString(charRefOneCharBuf, 0, 1); } return charRefOneCharBuf; } else { // [68] EntityRef ::= '&' Name ';' // scan name until ; if(!isNameStartChar(ch)) { throw new XmlPullParserException( "entity reference names can not start with character '" +printable(ch)+"'", this, null); } while(true) { ch = more(); if(ch == ';') { break; } if(!isNameChar(ch)) { throw new XmlPullParserException( "entity reference name can not contain character " +printable(ch)+"'", this, null); } } posEnd = pos - 1; // determine what name maps to final int len = posEnd - posStart; if(len == 2 && buf[posStart] == 'l' && buf[posStart+1] == 't') { if(tokenize) { text = "<"; } charRefOneCharBuf[0] = '<'; return charRefOneCharBuf; //if(paramPC || isParserTokenizing) { // if(pcEnd >= pc.length) ensurePC(); // pc[pcEnd++] = '<'; //} } else if(len == 3 && buf[posStart] == 'a' && buf[posStart+1] == 'm' && buf[posStart+2] == 'p') { if(tokenize) { text = "&"; } charRefOneCharBuf[0] = '&'; return charRefOneCharBuf; } else if(len == 2 && buf[posStart] == 'g' && buf[posStart+1] == 't') { if(tokenize) { text = ">"; } charRefOneCharBuf[0] = '>'; return charRefOneCharBuf; } else if(len == 4 && buf[posStart] == 'a' && buf[posStart+1] == 'p' && buf[posStart+2] == 'o' && buf[posStart+3] == 's') { if(tokenize) { text = "'"; } charRefOneCharBuf[0] = '\''; return charRefOneCharBuf; } else if(len == 4 && buf[posStart] == 'q' && buf[posStart+1] == 'u' && buf[posStart+2] == 'o' && buf[posStart+3] == 't') { if(tokenize) { text = "\""; } charRefOneCharBuf[0] = '"'; return charRefOneCharBuf; } else { final char[] result = lookuEntityReplacement(len); if(result != null) { return result; } } if(tokenize) text = null; return null; } } protected char[] lookuEntityReplacement(int entitNameLen) throws XmlPullParserException, IOException { if(!allStringsInterned) { final int hash = fastHash(buf, posStart, posEnd - posStart); LOOP: for (int i = entityEnd - 1; i >= 0; --i) { if(hash == entityNameHash[ i ] && entitNameLen == entityNameBuf[ i ].length) { final char[] entityBuf = entityNameBuf[ i ]; for (int j = 0; j < entitNameLen; j++) { if(buf[posStart + j] != entityBuf[j]) continue LOOP; } if(tokenize) text = entityReplacement[ i ]; return entityReplacementBuf[ i ]; } } } else { entityRefName = newString(buf, posStart, posEnd - posStart); for (int i = entityEnd - 1; i >= 0; --i) { // take advantage that interning for newStirng is enforced if(entityRefName == entityName[ i ]) { if(tokenize) text = entityReplacement[ i ]; return entityReplacementBuf[ i ]; } } } return null; } protected void parseComment() throws XmlPullParserException, IOException { // implements XML 1.0 Section 2.5 Comments //ASSUMPTION: seen ch = more(); if(seenDashDash && ch != '>') { throw new XmlPullParserException( "in comment after two dashes (--) next character must be >" +" not "+printable(ch), this, null); } if(ch == '-') { if(!seenDash) { seenDash = true; } else { seenDashDash = true; seenDash = false; } } else if(ch == '>') { if(seenDashDash) { break; // found end sequence!!!! } else { seenDashDash = false; } seenDash = false; } else { seenDash = false; } if(normalizeIgnorableWS) { if(ch == '\r') { normalizedCR = true; //posEnd = pos -1; //joinPC(); // posEnd is already set if(!usePC) { posEnd = pos -1; if(posEnd > posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } } } catch(EOFException ex) { // detect EOF and create meaningful error ... throw new XmlPullParserException( "comment started on line "+curLine+" and column "+curColumn+" was not closed", this, ex); } if(tokenize) { posEnd = pos - 3; if(usePC) { pcEnd -= 2; } } } protected boolean parsePI() throws XmlPullParserException, IOException { // implements XML 1.0 Section 2.6 Processing Instructions // [16] PI ::= '' Char*)))? '?>' // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) //ASSUMPTION: seen //ch = more(); if(ch == '?') { seenQ = true; } else if(ch == '>') { if(seenQ) { break; // found end sequence!!!! } seenQ = false; } else { if(piTargetEnd == -1 && isS(ch)) { piTargetEnd = pos - 1 + bufAbsoluteStart; // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) if((piTargetEnd - piTargetStart) == 3) { if((buf[piTargetStart] == 'x' || buf[piTargetStart] == 'X') && (buf[piTargetStart+1] == 'm' || buf[piTargetStart+1] == 'M') && (buf[piTargetStart+2] == 'l' || buf[piTargetStart+2] == 'L') ) { if(piTargetStart > 3) { // posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } ch = more(); } } catch(EOFException ex) { // detect EOF and create meaningful error ... throw new XmlPullParserException( "processing instruction started on line "+curLine+" and column "+curColumn +" was not closed", this, ex); } if(piTargetEnd == -1) { piTargetEnd = pos - 2 + bufAbsoluteStart; //throw new XmlPullParserException( // "processing instruction must have PITarget name", this, null); } piTargetStart -= bufAbsoluteStart; piTargetEnd -= bufAbsoluteStart; if(tokenize) { posEnd = pos - 2; if(normalizeIgnorableWS) { --pcEnd; } } return true; } // protected final static char[] VERSION = {'v','e','r','s','i','o','n'}; // protected final static char[] NCODING = {'n','c','o','d','i','n','g'}; // protected final static char[] TANDALONE = {'t','a','n','d','a','l','o','n','e'}; // protected final static char[] YES = {'y','e','s'}; // protected final static char[] NO = {'n','o'}; protected final static char[] VERSION = "version".toCharArray(); protected final static char[] NCODING = "ncoding".toCharArray(); protected final static char[] TANDALONE = "tandalone".toCharArray(); protected final static char[] YES = "yes".toCharArray(); protected final static char[] NO = "no".toCharArray(); protected void parseXmlDecl(char ch) throws XmlPullParserException, IOException { // [23] XMLDecl ::= '' // first make sure that relative positions will stay OK preventBufferCompaction = true; bufStart = 0; // necessary to keep pos unchanged during expansion! // --- parse VersionInfo // [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') // parse is positioned just on first S past 'z') && (ch < 'A' || ch > 'Z') && (ch < '0' || ch > '9') && ch != '_' && ch != '.' && ch != ':' && ch != '-') { throw new XmlPullParserException( " 'z') && (ch < 'A' || ch > 'Z')) { throw new XmlPullParserException( " 'z') && (ch < 'A' || ch > 'Z') && (ch < '0' || ch > '9') && ch != '.' && ch != '_' && ch != '-') { throw new XmlPullParserException( " as last part of ') { throw new XmlPullParserException( "expected ?> as last part of ' int bracketLevel = 0; final boolean normalizeIgnorableWS = tokenize == true && roundtripSupported == false; boolean normalizedCR = false; while(true) { ch = more(); if(ch == '[') ++bracketLevel; if(ch == ']') --bracketLevel; if(ch == '>' && bracketLevel == 0) break; if(normalizeIgnorableWS) { if(ch == '\r') { normalizedCR = true; //posEnd = pos -1; //joinPC(); // posEnd is alreadys set if(!usePC) { posEnd = pos -1; if(posEnd > posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } } posEnd = pos - 1; } protected void parseCDSect(boolean hadCharData) throws XmlPullParserException, IOException { // implements XML 1.0 Section 2.7 CDATA Sections // [18] CDSect ::= CDStart CData CDEnd // [19] CDStart ::= '' Char*)) // [21] CDEnd ::= ']]>' //ASSUMPTION: seen posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } } } boolean seenBracket = false; boolean seenBracketBracket = false; boolean normalizedCR = false; while(true) { // scan until it hits "]]>" ch = more(); if(ch == ']') { if(!seenBracket) { seenBracket = true; } else { seenBracketBracket = true; //seenBracket = false; } } else if(ch == '>') { if(seenBracket && seenBracketBracket) { break; // found end sequence!!!! } else { seenBracketBracket = false; } seenBracket = false; } else { if(seenBracket) { seenBracket = false; } } if(normalizeInput) { // deal with normalization issues ... if(ch == '\r') { normalizedCR = true; posStart = cdStart - bufAbsoluteStart; posEnd = pos - 1; // posEnd is alreadys set if(!usePC) { if(posEnd > posStart) { joinPC(); } else { usePC = true; pcStart = pcEnd = 0; } } //assert usePC == true; if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } else if(ch == '\n') { if(!normalizedCR && usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = '\n'; } normalizedCR = false; } else { if(usePC) { if(pcEnd >= pc.length) ensurePC(pcEnd); pc[pcEnd++] = ch; } normalizedCR = false; } } } } catch(EOFException ex) { // detect EOF and create meaningful error ... throw new XmlPullParserException( "CDATA section started on line "+curLine+" and column "+curColumn+" was not closed", this, ex); } if(normalizeInput) { if(usePC) { pcEnd = pcEnd - 2; } } posStart = cdStart - bufAbsoluteStart; posEnd = pos - 3; } protected void fillBuf() throws IOException, XmlPullParserException { if(reader == null) throw new XmlPullParserException( "reader must be set before parsing is started"); // see if we are in compaction area if(bufEnd > bufSoftLimit) { // expand buffer it makes sense!!!! boolean compact = bufStart > bufSoftLimit; boolean expand = false; if(preventBufferCompaction) { compact = false; expand = true; } else if(!compact) { //freeSpace if(bufStart < buf.length / 2) { // less then half buffer available forcompactin --> expand instead!!! expand = true; } else { // at least half of buffer can be reclaimed --> worthwhile effort!!! compact = true; } } // if buffer almost full then compact it if(compact) { //TODO: look on trashing // //assert bufStart > 0 System.arraycopy(buf, bufStart, buf, 0, bufEnd - bufStart); if(TRACE_SIZING) System.out.println( "TRACE_SIZING fillBuf() compacting "+bufStart +" bufEnd="+bufEnd +" pos="+pos+" posStart="+posStart+" posEnd="+posEnd +" buf first 100 chars:"+new String(buf, bufStart, bufEnd - bufStart < 100 ? bufEnd - bufStart : 100 )); } else if(expand) { final int newSize = 2 * buf.length; final char newBuf[] = new char[ newSize ]; if(TRACE_SIZING) System.out.println("TRACE_SIZING fillBuf() "+buf.length+" => "+newSize); System.arraycopy(buf, bufStart, newBuf, 0, bufEnd - bufStart); buf = newBuf; if(bufLoadFactor > 0) { //bufSoftLimit = ( bufLoadFactor * buf.length ) /100; bufSoftLimit = (int) (( ((long) bufLoadFactor) * buf.length ) /100); } } else { throw new XmlPullParserException("internal error in fillBuffer()"); } bufEnd -= bufStart; pos -= bufStart; posStart -= bufStart; posEnd -= bufStart; bufAbsoluteStart += bufStart; bufStart = 0; if(TRACE_SIZING) System.out.println( "TRACE_SIZING fillBuf() after bufEnd="+bufEnd +" pos="+pos+" posStart="+posStart+" posEnd="+posEnd +" buf first 100 chars:"+new String(buf, 0, bufEnd < 100 ? bufEnd : 100)); } // at least one character must be read or error final int len = buf.length - bufEnd > READ_CHUNK_SIZE ? READ_CHUNK_SIZE : buf.length - bufEnd; final int ret = reader.read(buf, bufEnd, len); if(ret > 0) { bufEnd += ret; if(TRACE_SIZING) System.out.println( "TRACE_SIZING fillBuf() after filling in buffer" +" buf first 100 chars:"+new String(buf, 0, bufEnd < 100 ? bufEnd : 100)); return; } if(ret == -1) { if(bufAbsoluteStart == 0 && pos == 0) { throw new EOFException("input contained no data"); } else { if(seenRoot && depth == 0) { // inside parsing epilog!!! reachedEnd = true; return; } else { StringBuffer expectedTagStack = new StringBuffer(); if(depth > 0) { //final char[] cbuf = elRawName[depth]; //final String startname = new String(cbuf, 0, elRawNameEnd[depth]); expectedTagStack.append(" - expected end tag"); if(depth > 1) { expectedTagStack.append("s"); //more than one end tag } expectedTagStack.append(" "); for (int i = depth; i > 0; i--) { String tagName = new String(elRawName[i], 0, elRawNameEnd[i]); expectedTagStack.append("'); } expectedTagStack.append(" to close"); for (int i = depth; i > 0; i--) { if(i != depth) { expectedTagStack.append(" and"); //more than one end tag } String tagName = new String(elRawName[i], 0, elRawNameEnd[i]); expectedTagStack.append(" start tag <"+tagName+">"); expectedTagStack.append(" from line "+elRawNameLine[i]); } expectedTagStack.append(", parser stopped on"); } throw new EOFException("no more data available" +expectedTagStack.toString()+getPositionDescription()); } } } else { throw new IOException("error reading input, returned "+ret); } } protected char more() throws IOException, XmlPullParserException { if(pos >= bufEnd) { fillBuf(); // this return value should be ignonored as it is used in epilog parsing ... if(reachedEnd) return (char)-1; } final char ch = buf[pos++]; //line/columnNumber if(ch == '\n') { ++lineNumber; columnNumber = 1; } else { ++columnNumber; } //System.out.print(ch); return ch; } // /** // * This function returns position of parser in XML input stream // * (how many characters were processed. // *

NOTE: this logical position and not byte offset as encodings // * such as UTF8 may use more than one byte to encode one character. // */ // public int getCurrentInputPosition() { // return pos + bufAbsoluteStart; // } protected void ensurePC(int end) { //assert end >= pc.length; final int newSize = end > READ_CHUNK_SIZE ? 2 * end : 2 * READ_CHUNK_SIZE; final char[] newPC = new char[ newSize ]; if(TRACE_SIZING) System.out.println("TRACE_SIZING ensurePC() "+pc.length+" ==> "+newSize+" end="+end); System.arraycopy(pc, 0, newPC, 0, pcEnd); pc = newPC; //assert end < pc.length; } protected void joinPC() { //assert usePC == false; //assert posEnd > posStart; final int len = posEnd - posStart; final int newEnd = pcEnd + len + 1; if(newEnd >= pc.length) ensurePC(newEnd); // add 1 for extra space for one char //assert newEnd < pc.length; System.arraycopy(buf, posStart, pc, pcEnd, len); pcEnd += len; usePC = true; } protected char requireInput(char ch, char[] input) throws XmlPullParserException, IOException { for (int i = 0; i < input.length; i++) { if(ch != input[i]) { throw new XmlPullParserException( "expected "+printable(input[i])+" in "+new String(input) +" and not "+printable(ch), this, null); } ch = more(); } return ch; } protected char requireNextS() throws XmlPullParserException, IOException { final char ch = more(); if(!isS(ch)) { throw new XmlPullParserException( "white space is required and not "+printable(ch), this, null); } return skipS(ch); } protected char skipS(char ch) throws XmlPullParserException, IOException { while(isS(ch)) { ch = more(); } // skip additional spaces return ch; } // nameStart / name lookup tables based on XML 1.1 http://www.w3.org/TR/2001/WD-xml11-20011213/ protected static final int LOOKUP_MAX = 0x400; protected static final char LOOKUP_MAX_CHAR = (char)LOOKUP_MAX; // protected static int lookupNameStartChar[] = new int[ LOOKUP_MAX_CHAR / 32 ]; // protected static int lookupNameChar[] = new int[ LOOKUP_MAX_CHAR / 32 ]; protected static boolean lookupNameStartChar[] = new boolean[ LOOKUP_MAX ]; protected static boolean lookupNameChar[] = new boolean[ LOOKUP_MAX ]; private static final void setName(char ch) //{ lookupNameChar[ (int)ch / 32 ] |= (1 << (ch % 32)); } { lookupNameChar[ ch ] = true; } private static final void setNameStart(char ch) //{ lookupNameStartChar[ (int)ch / 32 ] |= (1 << (ch % 32)); setName(ch); } { lookupNameStartChar[ ch ] = true; setName(ch); } static { setNameStart(':'); for (char ch = 'A'; ch <= 'Z'; ++ch) setNameStart(ch); setNameStart('_'); for (char ch = 'a'; ch <= 'z'; ++ch) setNameStart(ch); for (char ch = '\u00c0'; ch <= '\u02FF'; ++ch) setNameStart(ch); for (char ch = '\u0370'; ch <= '\u037d'; ++ch) setNameStart(ch); for (char ch = '\u037f'; ch < '\u0400'; ++ch) setNameStart(ch); setName('-'); setName('.'); for (char ch = '0'; ch <= '9'; ++ch) setName(ch); setName('\u00b7'); for (char ch = '\u0300'; ch <= '\u036f'; ++ch) setName(ch); } //private final static boolean isNameStartChar(char ch) { protected boolean isNameStartChar(char ch) { return (ch < LOOKUP_MAX_CHAR && lookupNameStartChar[ ch ]) || (ch >= LOOKUP_MAX_CHAR && ch <= '\u2027') || (ch >= '\u202A' && ch <= '\u218F') || (ch >= '\u2800' && ch <= '\uFFEF') ; // if(ch < LOOKUP_MAX_CHAR) return lookupNameStartChar[ ch ]; // else return ch <= '\u2027' // || (ch >= '\u202A' && ch <= '\u218F') // || (ch >= '\u2800' && ch <= '\uFFEF') // ; //return false; // return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == ':' // || (ch >= '0' && ch <= '9'); // if(ch < LOOKUP_MAX_CHAR) return (lookupNameStartChar[ (int)ch / 32 ] & (1 << (ch % 32))) != 0; // if(ch <= '\u2027') return true; // //[#x202A-#x218F] // if(ch < '\u202A') return false; // if(ch <= '\u218F') return true; // // added pairts [#x2800-#xD7FF] | [#xE000-#xFDCF] | [#xFDE0-#xFFEF] | [#x10000-#x10FFFF] // if(ch < '\u2800') return false; // if(ch <= '\uFFEF') return true; // return false; // else return (supportXml11 && ( (ch < '\u2027') || (ch > '\u2029' && ch < '\u2200') ... } //private final static boolean isNameChar(char ch) { protected boolean isNameChar(char ch) { //return isNameStartChar(ch); // if(ch < LOOKUP_MAX_CHAR) return (lookupNameChar[ (int)ch / 32 ] & (1 << (ch % 32))) != 0; return (ch < LOOKUP_MAX_CHAR && lookupNameChar[ ch ]) || (ch >= LOOKUP_MAX_CHAR && ch <= '\u2027') || (ch >= '\u202A' && ch <= '\u218F') || (ch >= '\u2800' && ch <= '\uFFEF') ; //return false; // return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == ':' // || (ch >= '0' && ch <= '9'); // if(ch < LOOKUP_MAX_CHAR) return (lookupNameStartChar[ (int)ch / 32 ] & (1 << (ch % 32))) != 0; //else return // else if(ch <= '\u2027') return true; // //[#x202A-#x218F] // else if(ch < '\u202A') return false; // else if(ch <= '\u218F') return true; // // added pairts [#x2800-#xD7FF] | [#xE000-#xFDCF] | [#xFDE0-#xFFEF] | [#x10000-#x10FFFF] // else if(ch < '\u2800') return false; // else if(ch <= '\uFFEF') return true; //else return false; } protected boolean isS(char ch) { return (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'); // || (supportXml11 && (ch == '\u0085' || ch == '\u2028'); } //protected boolean isChar(char ch) { return (ch < '\uD800' || ch > '\uDFFF') // ch != '\u0000' ch < '\uFFFE' //protected char printable(char ch) { return ch; } protected String printable(char ch) { if(ch == '\n') { return "\\n"; } else if(ch == '\r') { return "\\r"; } else if(ch == '\t') { return "\\t"; } else if(ch == '\'') { return "\\'"; } if(ch > 127 || ch < 32) { return "\\u"+Integer.toHexString((int)ch); } return ""+ch; } protected String printable(String s) { if(s == null) return null; final int sLen = s.length(); StringBuffer buf = new StringBuffer(sLen + 10); for(int i = 0; i < sLen; ++i) { buf.append(printable(s.charAt(i))); } s = buf.toString(); return s; } } /* * Indiana University Extreme! Lab Software License, Version 1.2 * * Copyright (C) 2003 The Trustees of Indiana University. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1) All redistributions of source code must retain the above * copyright notice, the list of authors in the original source * code, this list of conditions and the disclaimer listed in this * license; * * 2) All redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the disclaimer * listed in this license in the documentation and/or other * materials provided with the distribution; * * 3) Any documentation included with all redistributions must include * the following acknowledgement: * * "This product includes software developed by the Indiana * University Extreme! Lab. For further information please visit * http://www.extreme.indiana.edu/" * * Alternatively, this acknowledgment may appear in the software * itself, and wherever such third-party acknowledgments normally * appear. * * 4) The name "Indiana University" or "Indiana University * Extreme! Lab" shall not be used to endorse or promote * products derived from this software without prior written * permission from Indiana University. For written permission, * please contact http://www.extreme.indiana.edu/. * * 5) Products derived from this software may not use "Indiana * University" name nor may "Indiana University" appear in their name, * without prior written permission of the Indiana University. * * Indiana University provides no reassurances that the source code * provided does not infringe the patent or any other intellectual * property rights of any other entity. Indiana University disclaims any * liability to any recipient for claims brought by any other entity * based on infringement of intellectual property rights or otherwise. * * LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH * NO WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA * UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT * SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR * OTHER PROPRIETARY RIGHTS. INDIANA UNIVERSITY MAKES NO WARRANTIES THAT * SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP * DOORS", "WORMS", OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE * RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS, * AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING * SOFTWARE. */ jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/xml/XmlPullParser.java000066400000000000000000001311011257205723500275730ustar00rootroot00000000000000/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/) package org.jboss.modules.xml; import java.io.IOException; import java.io.InputStream; import java.io.Reader; /** * XML Pull Parser is an interface that defines parsing functionlity provided * in XMLPULL V1 API (visit this website to * learn more about API and its implementations). * *

There are following different * kinds of parser depending on which features are set:

    *
  • non-validating parser as defined in XML 1.0 spec when * FEATURE_PROCESS_DOCDECL is set to true *
  • validating parser as defined in XML 1.0 spec when * FEATURE_VALIDATION is true (and that implies that FEATURE_PROCESS_DOCDECL is true) *
  • when FEATURE_PROCESS_DOCDECL is false (this is default and * if different value is required necessary must be changed before parsing is started) * then parser behaves like XML 1.0 compliant non-validating parser under condition that * no DOCDECL is present in XML documents * (internal entites can still be defined with defineEntityReplacementText()). * This mode of operation is intened for operation in constrained environments such as J2ME. *
* * *

There are two key methods: next() and nextToken(). While next() provides * access to high level parsing events, nextToken() allows access to lower * level tokens. * *

The current event state of the parser * can be determined by calling the * getEventType() method. * Initially, the parser is in the START_DOCUMENT * state. * *

The method next() advances the parser to the * next event. The int value returned from next determines the current parser * state and is identical to the value returned from following calls to * getEventType (). * *

Th following event types are seen by next()

*
START_TAG
An XML start tag was read. *
TEXT
Text content was read; * the text content can be retreived using the getText() method. * (when in validating mode next() will not report ignorable whitespaces, use nextToken() instead) *
END_TAG
An end tag was read *
END_DOCUMENT
No more events are available *
* *

after first next() or nextToken() (or any other next*() method) * is called user application can obtain * XML version, standalone and encoding from XML declaration * in following ways:

    *
  • version: * getProperty("http://xmlpull.org/v1/doc/properties.html#xmldecl-version") * returns String ("1.0") or null if XMLDecl was not read or if property is not supported *
  • standalone: * getProperty("http://xmlpull.org/v1/doc/features.html#xmldecl-standalone") * returns Boolean: null if there was no standalone declaration * or if property is not supported * otherwise returns Boolean(true) if standalon="yes" and Boolean(false) when standalone="no" *
  • encoding: obtained from getInputEncoding() * null if stream had unknown encoding (not set in setInputStream) * and it was not declared in XMLDecl *
* * A minimal example for using this API may look as follows: *
 * import java.io.IOException;
 * import java.io.StringReader;
 *
 * import org.xmlpull.v1.XmlPullParser;
 * import org.xmlpull.v1.XmlPullParserException.html;
 * import org.xmlpull.v1.XmlPullParserFactory;
 *
 * public class SimpleXmlPullApp
 * {
 *
 *     public static void main (String args[])
 *         throws XmlPullParserException, IOException
 *     {
 *         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
 *         factory.setNamespaceAware(true);
 *         XmlPullParser xpp = factory.newPullParser();
 *
 *         xpp.setInput( new StringReader ( "<foo>Hello World!</foo>" ) );
 *         int eventType = xpp.getEventType();
 *         while (eventType != XmlPullParser.END_DOCUMENT) {
 *          if(eventType == XmlPullParser.START_DOCUMENT) {
 *              System.out.println("Start document");
 *          } else if(eventType == XmlPullParser.END_DOCUMENT) {
 *              System.out.println("End document");
 *          } else if(eventType == XmlPullParser.START_TAG) {
 *              System.out.println("Start tag "+xpp.getName());
 *          } else if(eventType == XmlPullParser.END_TAG) {
 *              System.out.println("End tag "+xpp.getName());
 *          } else if(eventType == XmlPullParser.TEXT) {
 *              System.out.println("Text "+xpp.getText());
 *          }
 *          eventType = xpp.next();
 *         }
 *     }
 * }
 * 
* *

The above example will generate the following output: *

 * Start document
 * Start tag foo
 * Text Hello World!
 * End tag foo
 * 
* *

For more details on API usage, please refer to the * quick Introduction available at http://www.xmlpull.org * * @see XmlPullParserFactory * @see #defineEntityReplacementText * @see #getName * @see #getNamespace * @see #getText * @see #next * @see #nextToken * @see #setInput * @see #FEATURE_PROCESS_DOCDECL * @see #FEATURE_VALIDATION * @see #START_DOCUMENT * @see #START_TAG * @see #TEXT * @see #END_TAG * @see #END_DOCUMENT * * @author Stefan Haustein * @author Aleksander Slominski */ public interface XmlPullParser { /** This constant represents the default namespace (empty string "") */ String NO_NAMESPACE = ""; // ---------------------------------------------------------------------------- // EVENT TYPES as reported by next() /** * Signalize that parser is at the very beginning of the document * and nothing was read yet. * This event type can only be observed by calling getEvent() * before the first call to next(), nextToken, or nextTag()). * * @see #next * @see #nextToken */ int START_DOCUMENT = 0; /** * Logical end of the xml document. Returned from getEventType, next() * and nextToken() * when the end of the input document has been reached. *

NOTE: calling again * next() or nextToken() * will result in exception being thrown. * * @see #next * @see #nextToken */ int END_DOCUMENT = 1; /** * Returned from getEventType(), * next(), nextToken() when * a start tag was read. * The name of start tag is available from getName(), its namespace and prefix are * available from getNamespace() and getPrefix() * if namespaces are enabled. * See getAttribute* methods to retrieve element attributes. * See getNamespace* methods to retrieve newly declared namespaces. * * @see #next * @see #nextToken * @see #getName * @see #getPrefix * @see #getNamespace * @see #getAttributeCount * @see #getDepth * @see #getNamespaceCount * @see #getNamespace * @see #FEATURE_PROCESS_NAMESPACES */ int START_TAG = 2; /** * Returned from getEventType(), next(), or * nextToken() when an end tag was read. * The name of start tag is available from getName(), its * namespace and prefix are * available from getNamespace() and getPrefix(). * * @see #next * @see #nextToken * @see #getName * @see #getPrefix * @see #getNamespace * @see #FEATURE_PROCESS_NAMESPACES */ int END_TAG = 3; /** * Character data was read and will is available by calling getText(). *

Please note: next() will * accumulate multiple * events into one TEXT event, skipping IGNORABLE_WHITESPACE, * PROCESSING_INSTRUCTION and COMMENT events, * In contrast, nextToken() will stop reading * text when any other event is observed. * Also, when the state was reached by calling next(), the text value will * be normalized, whereas getText() will * return unnormalized content in the case of nextToken(). This allows * an exact roundtrip without chnanging line ends when examining low * level events, whereas for high level applications the text is * normalized apropriately. * * @see #next * @see #nextToken * @see #getText */ int TEXT = 4; // ---------------------------------------------------------------------------- // additional events exposed by lower level nextToken() /** * A CDATA sections was just read; * this token is available only from calls to nextToken(). * A call to next() will accumulate various text events into a single event * of type TEXT. The text contained in the CDATA section is available * by callling getText(). * * @see #nextToken * @see #getText */ int CDSECT = 5; /** * An entity reference was just read; * this token is available from nextToken() * only. The entity name is available by calling getName(). If available, * the replacement text can be obtained by calling getTextt(); otherwise, * the user is responsibile for resolving the entity reference. * This event type is never returned from next(); next() will * accumulate the replacement text and other text * events to a single TEXT event. * * @see #nextToken * @see #getText */ int ENTITY_REF = 6; /** * Ignorable whitespace was just read. * This token is available only from nextToken()). * For non-validating * parsers, this event is only reported by nextToken() when outside * the root element. * Validating parsers may be able to detect ignorable whitespace at * other locations. * The ignorable whitespace string is available by calling getText() * *

NOTE: this is different from calling the * isWhitespace() method, since text content * may be whitespace but not ignorable. * * Ignorable whitespace is skipped by next() automatically; this event * type is never returned from next(). * * @see #nextToken * @see #getText */ int IGNORABLE_WHITESPACE = 7; /** * An XML processing instruction declaration was just read. This * event type is available only via nextToken(). * getText() will return text that is inside the processing instruction. * Calls to next() will skip processing instructions automatically. * @see #nextToken * @see #getText */ int PROCESSING_INSTRUCTION = 8; /** * An XML comment was just read. This event type is this token is * available via nextToken() only; * calls to next() will skip comments automatically. * The content of the comment can be accessed using the getText() * method. * * @see #nextToken * @see #getText */ int COMMENT = 9; /** * An XML document type declaration was just read. This token is * available from nextToken() only. * The unparsed text inside the doctype is available via * the getText() method. * * @see #nextToken * @see #getText */ int DOCDECL = 10; /** * This array can be used to convert the event type integer constants * such as START_TAG or TEXT to * to a string. For example, the value of TYPES[START_TAG] is * the string "START_TAG". * * This array is intended for diagnostic output only. Relying * on the contents of the array may be dangerous since malicous * applications may alter the array, although it is final, due * to limitations of the Java language. */ String [] TYPES = { "START_DOCUMENT", "END_DOCUMENT", "START_TAG", "END_TAG", "TEXT", "CDSECT", "ENTITY_REF", "IGNORABLE_WHITESPACE", "PROCESSING_INSTRUCTION", "COMMENT", "DOCDECL" }; // ---------------------------------------------------------------------------- // namespace related features /** * This feature determines whether the parser processes * namespaces. As for all features, the default value is false. *

NOTE: The value can not be changed during * parsing an must be set before parsing. * * @see #getFeature * @see #setFeature */ String FEATURE_PROCESS_NAMESPACES = "http://xmlpull.org/v1/doc/features.html#process-namespaces"; /** * This feature determines whether namespace attributes are * exposed via the attribute access methods. Like all features, * the default value is false. This feature cannot be changed * during parsing. * * @see #getFeature * @see #setFeature */ String FEATURE_REPORT_NAMESPACE_ATTRIBUTES = "http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes"; /** * This feature determines whether the document declaration * is processed. If set to false, * the DOCDECL event type is reported by nextToken() * and ignored by next(). * * If this featue is activated, then the document declaration * must be processed by the parser. * *

Please note: If the document type declaration * was ignored, entity references may cause exceptions * later in the parsing process. * The default value of this feature is false. It cannot be changed * during parsing. * * @see #getFeature * @see #setFeature */ String FEATURE_PROCESS_DOCDECL = "http://xmlpull.org/v1/doc/features.html#process-docdecl"; /** * If this feature is activated, all validation errors as * defined in the XML 1.0 sepcification are reported. * This implies that FEATURE_PROCESS_DOCDECL is true and both, the * internal and external document type declaration will be processed. *

Please Note: This feature can not be changed * during parsing. The default value is false. * * @see #getFeature * @see #setFeature */ String FEATURE_VALIDATION = "http://xmlpull.org/v1/doc/features.html#validation"; /** * Use this call to change the general behaviour of the parser, * such as namespace processing or doctype declaration handling. * This method must be called before the first call to next or * nextToken. Otherwise, an exception is thrown. *

Example: call setFeature(FEATURE_PROCESS_NAMESPACES, true) in order * to switch on namespace processing. The initial settings correspond * to the properties requested from the XML Pull Parser factory. * If none were requested, all feautures are deactivated by default. * * @exception XmlPullParserException If the feature is not supported or can not be set * @exception IllegalArgumentException If string with the feature name is null */ void setFeature(String name, boolean state) throws XmlPullParserException; /** * Returns the current value of the given feature. *

Please note: unknown features are * always returned as false. * * @param name The name of feature to be retrieved. * @return The value of the feature. * @exception IllegalArgumentException if string the feature name is null */ boolean getFeature(String name); /** * Set the value of a property. * * The property name is any fully-qualified URI. * * @exception XmlPullParserException If the property is not supported or can not be set * @exception IllegalArgumentException If string with the property name is null */ void setProperty(String name, Object value) throws XmlPullParserException; /** * Look up the value of a property. * * The property name is any fully-qualified URI. *

NOTE: unknown properties are always * returned as null. * * @param name The name of property to be retrieved. * @return The value of named property. */ Object getProperty(String name); /** * Set the input source for parser to the given reader and * resets the parser. The event type is set to the initial value * START_DOCUMENT. * Setting the reader to null will just stop parsing and * reset parser state, * allowing the parser to free internal resources * such as parsing buffers. */ void setInput(Reader in) throws XmlPullParserException; /** * Sets the input stream the parser is going to process. * This call resets the parser state and sets the event type * to the initial value START_DOCUMENT. * *

NOTE: If an input encoding string is passed, * it MUST be used. Otherwise, * if inputEncoding is null, the parser SHOULD try to determine * input encoding following XML 1.0 specification (see below). * If encoding detection is supported then following feature * http://xmlpull.org/v1/doc/features.html#detect-encoding * MUST be true amd otherwise it must be false * * @param inputStream contains a raw byte input stream of possibly * unknown encoding (when inputEncoding is null). * * @param inputEncoding if not null it MUST be used as encoding for inputStream */ void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException; /** * Returns the input encoding if known, null otherwise. * If setInput(InputStream, inputEncoding) was called with an inputEncoding * value other than null, this value must be returned * from this method. Otherwise, if inputEncoding is null and * the parser suppports the encoding detection feature * (http://xmlpull.org/v1/doc/features.html#detect-encoding), * it must return the detected encoding. * If setInput(Reader) was called, null is returned. * After first call to next if XML declaration was present this method * will return encoding declared. */ String getInputEncoding(); /** * Set new value for entity replacement text as defined in * XML 1.0 Section 4.5 * Construction of Internal Entity Replacement Text. * If FEATURE_PROCESS_DOCDECL or FEATURE_VALIDATION are set, calling this * function will result in an exception -- when processing of DOCDECL is * enabled, there is no need to the entity replacement text manually. * *

The motivation for this function is to allow very small * implementations of XMLPULL that will work in J2ME environments. * Though these implementations may not be able to process the document type * declaration, they still can work with known DTDs by using this function. * *

Please notes: The given value is used literally as replacement text * and it corresponds to declaring entity in DTD that has all special characters * escaped: left angle bracket is replaced with &lt;, ampersnad with &amp; * and so on. * *

Note: The given value is the literal replacement text and must not * contain any other entity reference (if it contains any entity reference * there will be no further replacement). * *

Note: The list of pre-defined entity names will * always contain standard XML entities such as * amp (&amp;), lt (&lt;), gt (&gt;), quot (&quot;), and apos (&apos;). * Those cannot be redefined by this method! * * @see #setInput * @see #FEATURE_PROCESS_DOCDECL * @see #FEATURE_VALIDATION */ void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException; /** * Returns the numbers of elements in the namespace stack for the given * depth. * If namespaces are not enabled, 0 is returned. * *

NOTE: when parser is on END_TAG then it is allowed to call * this function with getDepth()+1 argument to retrieve position of namespace * prefixes and URIs that were declared on corresponding START_TAG. *

NOTE: to retrieve lsit of namespaces declared in current element:

     *       XmlPullParser pp = ...
     *       int nsStart = pp.getNamespaceCount(pp.getDepth()-1);
     *       int nsEnd = pp.getNamespaceCount(pp.getDepth());
     *       for (int i = nsStart; i < nsEnd; i++) {
     *          String prefix = pp.getNamespacePrefix(i);
     *          String ns = pp.getNamespaceUri(i);
     *           // ...
     *      }
     * 
* * @see #getNamespacePrefix * @see #getNamespaceUri * @see #getNamespace() * @see #getNamespace(String) */ int getNamespaceCount(int depth) throws XmlPullParserException; /** * Returns the namespace prefixe for the given position * in the namespace stack. * Default namespace declaration (xmlns='...') will have null as prefix. * If the given index is out of range, an exception is thrown. *

Please note: when the parser is on an END_TAG, * namespace prefixes that were declared * in the corresponding START_TAG are still accessible * although they are no longer in scope. */ String getNamespacePrefix(int pos) throws XmlPullParserException; /** * Returns the namespace URI for the given position in the * namespace stack * If the position is out of range, an exception is thrown. *

NOTE: when parser is on END_TAG then namespace prefixes that were declared * in corresponding START_TAG are still accessible even though they are not in scope */ String getNamespaceUri(int pos) throws XmlPullParserException; /** * Returns the URI corresponding to the given prefix, * depending on current state of the parser. * *

If the prefix was not declared in the current scope, * null is returned. The default namespace is included * in the namespace table and is available via * getNamespace (null). * *

This method is a convenience method for * *

     *  for (int i = getNamespaceCount(getDepth ())-1; i >= 0; i--) {
     *   if (getNamespacePrefix(i).equals( prefix )) {
     *     return getNamespaceUri(i);
     *   }
     *  }
     *  return null;
     * 
* *

Please note: parser implementations * may provide more efifcient lookup, e.g. using a Hashtable. * The 'xml' prefix is bound to "http://www.w3.org/XML/1998/namespace", as * defined in the * Namespaces in XML * specification. Analogous, the 'xmlns' prefix is resolved to * http://www.w3.org/2000/xmlns/ * * @see #getNamespaceCount * @see #getNamespacePrefix * @see #getNamespaceUri */ String getNamespace(String prefix); // -------------------------------------------------------------------------- // miscellaneous reporting methods /** * Returns the current depth of the element. * Outside the root element, the depth is 0. The * depth is incremented by 1 when a start tag is reached. * The depth is decremented AFTER the end tag * event was observed. * *

     * <!-- outside -->     0
     * <root>                  1
     *   sometext                 1
     *     <foobar>         2
     *     </foobar>        2
     * </root>              1
     * <!-- outside -->     0
     * 
*/ int getDepth(); /** * Returns a short text describing the current parser state, including * the position, a * description of the current event and the data source if known. * This method is especially useful to provide meaningful * error messages and for debugging purposes. */ String getPositionDescription(); /** * Returns the current line number, starting from 1. * When the parser does not know the current line number * or can not determine it, -1 is returned (e.g. for WBXML). * * @return current line number or -1 if unknown. */ int getLineNumber(); /** * Returns the current column number, starting from 0. * When the parser does not know the current column number * or can not determine it, -1 is returned (e.g. for WBXML). * * @return current column number or -1 if unknown. */ int getColumnNumber(); // -------------------------------------------------------------------------- // TEXT related methods /** * Checks whether the current TEXT event contains only whitespace * characters. * For IGNORABLE_WHITESPACE, this is always true. * For TEXT and CDSECT, false is returned when the current event text * contains at least one non-white space character. For any other * event type an exception is thrown. * *

Please note: non-validating parsers are not * able to distinguish whitespace and ignorable whitespace, * except from whitespace outside the root element. Ignorable * whitespace is reported as separate event, which is exposed * via nextToken only. * */ boolean isWhitespace() throws XmlPullParserException; /** * Returns the text content of the current event as String. * The value returned depends on current event type, * for example for TEXT event it is element content * (this is typical case when next() is used). * * See description of nextToken() for detailed description of * possible returned values for different types of events. * *

NOTE: in case of ENTITY_REF, this method returns * the entity replacement text (or null if not available). This is * the only case where * getText() and getTextCharacters() return different values. * * @see #getEventType * @see #next * @see #nextToken */ String getText(); /** * Returns the buffer that contains the text of the current event, * as well as the start offset and length relevant for the current * event. See getText(), next() and nextToken() for description of possible returned values. * *

Please note: this buffer must not * be modified and its content MAY change after a call to * next() or nextToken(). This method will always return the * same value as getText(), except for ENTITY_REF. In the case * of ENTITY ref, getText() returns the replacement text and * this method returns the actual input buffer containing the * entity name. * If getText() returns null, this method returns null as well and * the values returned in the holder array MUST be -1 (both start * and length). * * @see #getText * @see #next * @see #nextToken * * @param holderForStartAndLength Must hold an 2-element int array * into which the start offset and length values will be written. * @return char buffer that contains the text of the current event * (null if the current event has no text associated). */ char[] getTextCharacters(int[] holderForStartAndLength); // -------------------------------------------------------------------------- // START_TAG / END_TAG shared methods /** * Returns the namespace URI of the current element. * The default namespace is represented * as empty string. * If namespaces are not enabled, an empty String ("") is always returned. * The current event must be START_TAG or END_TAG; otherwise, * null is returned. */ String getNamespace(); /** * For START_TAG or END_TAG events, the (local) name of the current * element is returned when namespaces are enabled. When namespace * processing is disabled, the raw name is returned. * For ENTITY_REF events, the entity name is returned. * If the current event is not START_TAG, END_TAG, or ENTITY_REF, * null is returned. *

Please note: To reconstruct the raw element name * when namespaces are enabled and the prefix is not null, * you will need to add the prefix and a colon to localName.. * */ String getName(); /** * Returns the prefix of the current element. * If the element is in the default namespace (has no prefix), * null is returned. * If namespaces are not enabled, or the current event * is not START_TAG or END_TAG, null is returned. */ String getPrefix(); /** * Returns true if the current event is START_TAG and the tag * is degenerated * (e.g. <foobar/>). *

NOTE: if the parser is not on START_TAG, an exception * will be thrown. */ boolean isEmptyElementTag() throws XmlPullParserException; // -------------------------------------------------------------------------- // START_TAG Attributes retrieval methods /** * Returns the number of attributes of the current start tag, or * -1 if the current event type is not START_TAG * * @see #getAttributeNamespace * @see #getAttributeName * @see #getAttributePrefix * @see #getAttributeValue */ int getAttributeCount(); /** * Returns the namespace URI of the attribute * with the given index (starts from 0). * Returns an empty string ("") if namespaces are not enabled * or the attribute has no namespace. * Throws an IndexOutOfBoundsException if the index is out of range * or the current event type is not START_TAG. * *

NOTE: if FEATURE_REPORT_NAMESPACE_ATTRIBUTES is set * then namespace attributes (xmlns:ns='...') must be reported * with namespace * http://www.w3.org/2000/xmlns/ * (visit this URL for description!). * The default namespace attribute (xmlns="...") will be reported with empty namespace. *

NOTE:The xml prefix is bound as defined in * Namespaces in XML * specification to "http://www.w3.org/XML/1998/namespace". * * @param zero based index of attribute * @return attribute namespace, * empty string ("") is returned if namesapces processing is not enabled or * namespaces processing is enabled but attribute has no namespace (it has no prefix). */ String getAttributeNamespace(int index); /** * Returns the local name of the specified attribute * if namespaces are enabled or just attribute name if namespaces are disabled. * Throws an IndexOutOfBoundsException if the index is out of range * or current event type is not START_TAG. * * @param zero based index of attribute * @return attribute name (null is never returned) */ String getAttributeName(int index); /** * Returns the prefix of the specified attribute * Returns null if the element has no prefix. * If namespaces are disabled it will always return null. * Throws an IndexOutOfBoundsException if the index is out of range * or current event type is not START_TAG. * * @param zero based index of attribute * @return attribute prefix or null if namespaces processing is not enabled. */ String getAttributePrefix(int index); /** * Returns the type of the specified attribute * If parser is non-validating it MUST return CDATA. * * @param zero based index of attribute * @return attribute type (null is never returned) */ String getAttributeType(int index); /** * Returns if the specified attribute was not in input was declared in XML. * If parser is non-validating it MUST always return false. * This information is part of XML infoset: * * @param zero based index of attribute * @return false if attribute was in input */ boolean isAttributeDefault(int index); /** * Returns the given attributes value. * Throws an IndexOutOfBoundsException if the index is out of range * or current event type is not START_TAG. * *

NOTE: attribute value must be normalized * (including entity replacement text if PROCESS_DOCDECL is false) as described in * XML 1.0 section * 3.3.3 Attribute-Value Normalization * * @see #defineEntityReplacementText * * @param zero based index of attribute * @return value of attribute (null is never returned) */ String getAttributeValue(int index); /** * Returns the attributes value identified by namespace URI and namespace localName. * If namespaces are disabled namespace must be null. * If current event type is not START_TAG then IndexOutOfBoundsException will be thrown. * *

NOTE: attribute value must be normalized * (including entity replacement text if PROCESS_DOCDECL is false) as described in * XML 1.0 section * 3.3.3 Attribute-Value Normalization * * @see #defineEntityReplacementText * * @param namespace Namespace of the attribute if namespaces are enabled otherwise must be null * @param name If namespaces enabled local name of attribute otherwise just attribute name * @return value of attribute or null if attribute with given name does not exist */ String getAttributeValue(String namespace, String name); // -------------------------------------------------------------------------- // actual parsing methods /** * Returns the type of the current event (START_TAG, END_TAG, TEXT, etc.) * * @see #next() * @see #nextToken() */ int getEventType(); /** * Get next parsing event - element content wil be coalesced and only one * TEXT event must be returned for whole element content * (comments and processing instructions will be ignored and emtity references * must be expanded or exception mus be thrown if entity reerence can not be exapnded). * If element content is empty (content is "") then no TEXT event will be reported. * *

NOTE: empty element (such as <tag/>) will be reported * with two separate events: START_TAG, END_TAG - it must be so to preserve * parsing equivalency of empty element to <tag></tag>. * (see isEmptyElementTag ()) * * @see #isEmptyElementTag * @see #START_TAG * @see #TEXT * @see #END_TAG * @see #END_DOCUMENT */ int next() throws XmlPullParserException, IOException; /** * This method works similarly to next() but will expose * additional event types (COMMENT, CDSECT, DOCDECL, ENTITY_REF, PROCESSING_INSTRUCTION, or * IGNORABLE_WHITESPACE) if they are available in input. * *

If special feature * FEATURE_XML_ROUNDTRIP * (identified by URI: http://xmlpull.org/v1/doc/features.html#xml-roundtrip) * is enabled it is possible to do XML document round trip ie. reproduce * exectly on output the XML input using getText(): * returned content is always unnormalized (exactly as in input). * Otherwise returned content is end-of-line normalized as described * XML 1.0 End-of-Line Handling * and. Also when this feature is enabled exact content of START_TAG, END_TAG, * DOCDECL and PROCESSING_INSTRUCTION is available. * *

Here is the list of tokens that can be returned from nextToken() * and what getText() and getTextCharacters() returns:

*
START_DOCUMENT
null *
END_DOCUMENT
null *
START_TAG
null unless FEATURE_XML_ROUNDTRIP * enabled and then returns XML tag, ex: <tag attr='val'> *
END_TAG
null unless FEATURE_XML_ROUNDTRIP * id enabled and then returns XML tag, ex: </tag> *
TEXT
return element content. *
Note: that element content may be delivered in multiple consecutive TEXT events. *
IGNORABLE_WHITESPACE
return characters that are determined to be ignorable white * space. If the FEATURE_XML_ROUNDTRIP is enabled all whitespace content outside root * element will always reported as IGNORABLE_WHITESPACE otherise rteporting is optional. *
Note: that element content may be delevered in multiple consecutive IGNORABLE_WHITESPACE events. *
CDSECT
* return text inside CDATA * (ex. 'fo<o' from <!CDATA[fo<o]]>) *
PROCESSING_INSTRUCTION
* if FEATURE_XML_ROUNDTRIP is true * return exact PI content ex: 'pi foo' from <?pi foo?> * otherwise it may be exact PI content or concatenation of PI target, * space and data so for example for * <?target data?> string "target data" may * be returned if FEATURE_XML_ROUNDTRIP is false. *
COMMENT
return comment content ex. 'foo bar' from <!--foo bar--> *
ENTITY_REF
getText() MUST return entity replacement text if PROCESS_DOCDECL is false * otherwise getText() MAY return null, * additionally getTextCharacters() MUST return entity name * (for example 'entity_name' for &entity_name;). *
NOTE: this is the only place where value returned from getText() and * getTextCharacters() are different *
NOTE: it is user responsibility to resolve entity reference * if PROCESS_DOCDECL is false and there is no entity replacement text set in * defineEntityReplacementText() method (getText() will be null) *
NOTE: character entities (ex. &#32;) and standard entities such as * &amp; &lt; &gt; &quot; &apos; are reported as well * and are not reported as TEXT tokens but as ENTITY_REF tokens! * This requirement is added to allow to do roundtrip of XML documents! *
DOCDECL
* if FEATURE_XML_ROUNDTRIP is true or PROCESS_DOCDECL is false * then return what is inside of DOCDECL for example it returns:
     * " titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
     * [<!ENTITY % active.links "INCLUDE">]"
*

for input document that contained:

     * <!DOCTYPE titlepage SYSTEM "http://www.foo.bar/dtds/typo.dtd"
     * [<!ENTITY % active.links "INCLUDE">]>
* otherwise if FEATURE_XML_ROUNDTRIP is false and PROCESS_DOCDECL is true * then what is returned is undefined (it may be even null) *
*
* *

NOTE: there is no gurantee that there will only one TEXT or * IGNORABLE_WHITESPACE event from nextToken() as parser may chose to deliver element content in * multiple tokens (dividing element content into chunks) * *

NOTE: whether returned text of token is end-of-line normalized * is depending on FEATURE_XML_ROUNDTRIP. * *

NOTE: XMLDecl (<?xml ...?>) is not reported but its content * is available through optional properties (see class description above). * * @see #next * @see #START_TAG * @see #TEXT * @see #END_TAG * @see #END_DOCUMENT * @see #COMMENT * @see #DOCDECL * @see #PROCESSING_INSTRUCTION * @see #ENTITY_REF * @see #IGNORABLE_WHITESPACE */ int nextToken() throws XmlPullParserException, IOException; //----------------------------------------------------------------------------- // utility methods to mak XML parsing easier ... /** * Test if the current event is of the given type and if the * namespace and name do match. null will match any namespace * and any name. If the test is not passed, an exception is * thrown. The exception text indicates the parser position, * the expected event and the current event that is not meeting the * requirement. * *

Essentially it does this *

     *  if (type != getEventType()
     *  || (namespace != null &&  !namespace.equals( getNamespace () ) )
     *  || (name != null &&  !name.equals( getName() ) ) )
     *     throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
     * 
*/ void require(int type, String namespace, String name) throws XmlPullParserException, IOException; /** * If current event is START_TAG then if next element is TEXT then element content is returned * or if next event is END_TAG then empty string is returned, otherwise exception is thrown. * After calling this function successfully parser will be positioned on END_TAG. * *

The motivation for this function is to allow to parse consistently both * empty elements and elements that has non empty content, for example for input:

    *
  1. <tag>foo</tag> *
  2. <tag></tag> (which is equivalent to <tag/> * both input can be parsed with the same code: *
         *   p.nextTag()
         *   p.requireEvent(p.START_TAG, "", "tag");
         *   String content = p.nextText();
         *   p.requireEvent(p.END_TAG, "", "tag");
         * 
    * This function together with nextTag make it very easy to parse XML that has * no mixed content. * * *

    Essentially it does this *

         *  if(getEventType() != START_TAG) {
         *     throw new XmlPullParserException(
         *       "parser must be on START_TAG to read next text", this, null);
         *  }
         *  int eventType = next();
         *  if(eventType == TEXT) {
         *     String result = getText();
         *     eventType = next();
         *     if(eventType != END_TAG) {
         *       throw new XmlPullParserException(
         *          "event TEXT it must be immediately followed by END_TAG", this, null);
         *      }
         *      return result;
         *  } else if(eventType == END_TAG) {
         *     return "";
         *  } else {
         *     throw new XmlPullParserException(
         *       "parser must be on START_TAG or TEXT to read text", this, null);
         *  }
         * 
    */ String nextText() throws XmlPullParserException, IOException; /** * Call next() and return event if it is START_TAG or END_TAG * otherwise throw an exception. * It will skip whitespace TEXT before actual tag if any. * *

    essentially it does this *

         *   int eventType = next();
         *   if(eventType == TEXT &&  isWhitespace()) {   // skip whitespace
         *      eventType = next();
         *   }
         *   if (eventType != START_TAG &&  eventType != END_TAG) {
         *      throw new XmlPullParserException("expected start or end tag", this, null);
         *   }
         *   return eventType;
         * 
    */ int nextTag() throws XmlPullParserException, IOException; // /** // * Skip sub tree on which the parser is currently positioned on. // *
    NOTE: parser must be on START_TAG and when function returns // * parser will be positioned on matching END_TAG // * // * This method is typically optimized by parser but the its logic should follow this: // * // * require(XmlPullParser.START_TAG, null, null); // * int level = 1; // * while(level > 0) { // * int eventType = next(); // * if(eventType == XmlPullParser.END_TAG) { // * --level; // * } else if(eventType == XmlPullParser.START_TAG) { // * ++level; // * } // * } // * // */ // public void skipSubTree() throws XmlPullParserException, IOException; } jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/xml/XmlPullParserException.java000066400000000000000000000043431257205723500314610ustar00rootroot00000000000000/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/) package org.jboss.modules.xml; /** * This exception is thrown to signal XML Pull Parser related faults. * * @author Aleksander Slominski */ public class XmlPullParserException extends Exception { protected Throwable detail; protected int row = -1; protected int column = -1; /* public XmlPullParserException() { }*/ public XmlPullParserException(String s) { super(s); } /* public XmlPullParserException(String s, Throwable thrwble) { super(s); this.detail = thrwble; } public XmlPullParserException(String s, int row, int column) { super(s); this.row = row; this.column = column; } */ public XmlPullParserException(String msg, XmlPullParser parser, Throwable chain) { super ((msg == null ? "" : msg+" ") + (parser == null ? "" : "(position:"+parser.getPositionDescription()+") ") + (chain == null ? "" : "caused by: "+chain)); if (parser != null) { this.row = parser.getLineNumber(); this.column = parser.getColumnNumber(); } this.detail = chain; } public Throwable getDetail() { return detail; } // public void setDetail(Throwable cause) { this.detail = cause; } public int getLineNumber() { return row; } public int getColumnNumber() { return column; } /* public String getMessage() { if(detail == null) return super.getMessage(); else return super.getMessage() + "; nested exception is: \n\t" + detail.getMessage(); } */ //NOTE: code that prints this and detail is difficult in J2ME public void printStackTrace() { if (detail == null) { super.printStackTrace(); } else { synchronized(System.err) { System.err.println(super.getMessage() + "; nested exception is:"); detail.printStackTrace(); } } } } jboss-modules-1.4.4.Final/src/main/resources/000077500000000000000000000000001257205723500210735ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/resources/XPP3-LICENSE.txt000066400000000000000000000042171257205723500234520ustar00rootroot00000000000000Indiana University Extreme! Lab Software License Version 1.1.1 Copyright (c) 2002 Extreme! Lab, Indiana University. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Indiana University Extreme! Lab (http://www.extreme.indiana.edu/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Indiana Univeristy" and "Indiana Univeristy Extreme! Lab" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact http://www.extreme.indiana.edu/. 5. Products derived from this software may not use "Indiana Univeristy" name nor may "Indiana Univeristy" appear in their name, without prior written permission of the Indiana University. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS, COPYRIGHT HOLDERS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jboss-modules-1.4.4.Final/src/main/resources/schema/000077500000000000000000000000001257205723500223335ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/main/resources/schema/module-1_0.xsd000066400000000000000000000515131257205723500247220ustar00rootroot00000000000000 Root element for a module declaration. Root element for a filesystem module loader configuration. The module declaration type; contains dependencies, resources, and the main class specification. Lists filter expressions to apply to the export filter of the local resources of this module (optional). By default, everything is exported. If filter expressions are provided, the default action is to accept all paths if no filters match. Lists the dependencies of this module (optional). Lists the resource roots of this module (optional). Specifies the main class of this module; used to run the module from the command-line (optional). The name of this module (required). The version slot of this module (optional). A module name, which consists of one or more dot (.)-separated segments. Each segment must begin and end with an alphanumeric or underscore (_), and may otherwise contain alphanumerics, underscores, and hyphens (-). A module version slot. A slot may consist of one or more alphanumerics, hyphens (-), underscores (_), plus signs (+), asterisks (*), or dots (.). A list of zero or more module dependencies. A specified module dependency. A single module dependency expression. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. A filter used to restrict what packages or directories from this dependency are visible to this module. See also the "services" attribute. The default action of this filter list is to reject a path if not matched. The dependency module name (required). The dependency module version slot (optional). Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. Specifies whether and how services found in this dependency are used (default is "none"). Specifying a value of "import" for this attribute is equivalent to adding a filter at the end of the import filter list which includes the META-INF/services path from the dependency module. Setting a value of "export" for this attribute is equivalent to the same action on the export filter list. Specifies whether this dependency is optional (defaults to false). An optional dependency will not cause the module to fail to load if not found; however if the module is added later, it will not be retroactively linked into this module's dependency list. The requested behavior for service handling on a dependency. Do not import or export services from this dependency. Import, but do not re-export, services from this dependency. Import and re-export services found in this dependency. A class name. The class name. A filesystem path name. The path name. A list of zero or more resource roots for this deployment. A resource root within this deployment. A resource root within a deployment. A path filter specification for this resource root (optional). By default all paths are accepted. The name of this resource root (optional). If not specified, defaults to the value of the path attribute. The path of this resource root, relative to the path in which the module.xml file is found. A filter specification, consisting of zero or more filter items. A path to include. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A path to exclude. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A set of literal path names to include. Wildcards are not supported. A set of literal path names to exclude. Wildcards are not supported. A path specification type, which may include wildcards. The path name, which can be a literal path name or it may include the special wildcards "*", "**", and "?". A set of literal path names which can be used for efficient matching against multiple possible values. The path name to include in the set. A configuration for the default module loader. A defined loader. More than one loader may be defined. The loader to use. The name matches the value of the "name" attribute of one of the defined loaders. A module root path for this loader. Paths are relative to ${user.dir} by default. Specifies another loader whose content should be imported. Such loaders are visible to modules defined by this loader, but not to modules defined in other loaders. The name of this particular module loader. A loader type name, which may consist of letters, numbers, hyphens, and underscores. jboss-modules-1.4.4.Final/src/main/resources/schema/module-1_1.xsd000066400000000000000000000650251257205723500247260ustar00rootroot00000000000000 Root element for a module declaration. Root element for a filesystem module loader configuration. Root element for a module alias declaration. The module declaration type; contains dependencies, resources, and the main class specification. Lists filter expressions to apply to the export filter of the local resources of this module (optional). By default, everything is exported. If filter expressions are provided, the default action is to accept all paths if no filters match. Lists the dependencies of this module (optional). Lists the resource roots of this module (optional). Specifies the main class of this module; used to run the module from the command-line (optional). Lists the user-defined properties to be associated with this module (optional). The name of this module (required). The version slot of this module (optional). A module name, which consists of one or more dot (.)-separated segments. Each segment must begin and end with an alphanumeric or underscore (_), and may otherwise contain alphanumerics, underscores, and hyphens (-). A module version slot. A slot may consist of one or more alphanumerics, hyphens (-), underscores (_), plus signs (+), asterisks (*), or dots (.). A list of zero or more module dependencies. A specified module dependency. A dependency on the system (or embedding) class loader. A single module dependency expression. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. A filter used to restrict what packages or directories from this dependency are visible to this module. See also the "services" attribute. The default action of this filter list is to reject a path if not matched. The dependency module name (required). The dependency module version slot (optional). Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. Specifies whether and how services found in this dependency are used (default is "none"). Specifying a value of "import" for this attribute is equivalent to adding a filter at the end of the import filter list which includes the META-INF/services path from the dependency module. Setting a value of "export" for this attribute is equivalent to the same action on the export filter list. Specifies whether this dependency is optional (defaults to false). An optional dependency will not cause the module to fail to load if not found; however if the module is added later, it will not be retroactively linked into this module's dependency list. The list of paths which are applicable for this system dependency. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. The requested behavior for service handling on a dependency. Do not import or export services from this dependency. Import, but do not re-export, services from this dependency. Import and re-export services found in this dependency. A class name. The class name. A filesystem path name. The path name. A list of zero or more resource roots for this deployment. A resource root within this deployment. A resource root within a deployment. A path filter specification for this resource root (optional). By default all paths are accepted. The name of this resource root (optional). If not specified, defaults to the value of the path attribute. The path of this resource root, relative to the path in which the module.xml file is found. A filter specification, consisting of zero or more filter items. A path to include. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A path to exclude. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A set of literal path names to include. Wildcards are not supported. A set of literal path names to exclude. Wildcards are not supported. A path specification type, which may include wildcards. The path name, which can be a literal path name or it may include the special wildcards "*", "**", and "?". A set of literal path names which can be used for efficient matching against multiple possible values. The path name to include in the set. A configuration for the default module loader. A defined loader. More than one loader may be defined. The loader to use. The name matches the value of the "name" attribute of one of the defined loaders. A module root path for this loader. Paths are relative to ${user.dir} by default. Specifies another loader whose content should be imported. Such loaders are visible to modules defined by this loader, but not to modules defined in other loaders. The name of this particular module loader. A loader type name, which may consist of letters, numbers, hyphens, and underscores. A module alias type, which defines the target for a module alias. The name of this module alias (required). The version slot of this module alias (optional). The name of the module to which this alias refers (required). The version slot of the module to which this alias refers (optional). A property in this property list. The property name as a string (required). The property value (optional, defaults to "true"). jboss-modules-1.4.4.Final/src/main/resources/schema/module-1_2.xsd000077500000000000000000000654511257205723500247350ustar00rootroot00000000000000 Root element for a module declaration. Root element for a module alias declaration. Root element for an absent module. The module declaration type; contains dependencies, resources, and the main class specification. Lists filter expressions to apply to the export filter of the local resources of this module (optional). By default, everything is exported. If filter expressions are provided, the default action is to accept all paths if no filters match. Lists the dependencies of this module (optional). Lists the resource roots of this module (optional). Specifies the main class of this module; used to run the module from the command-line (optional). Lists the user-defined properties to be associated with this module (optional). Lists the requested permission set for this module. If the requested permissions cannot be assigned, the module cannot be loaded. The name of this module (required). The version slot of this module (optional). A module name, which consists of one or more dot (.)-separated segments. Each segment must begin and end with an alphanumeric or underscore (_), and may otherwise contain alphanumerics, underscores, and hyphens (-). A module version slot. A slot may consist of one or more alphanumerics, hyphens (-), underscores (_), plus signs (+), asterisks (*), or dots (.). A list of zero or more module dependencies. A specified module dependency. A dependency on the system (or embedding) class loader. A single module dependency expression. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. A filter used to restrict what packages or directories from this dependency are visible to this module. See also the "services" attribute. The default action of this filter list is to reject a path if not matched. The dependency module name (required). The dependency module version slot (optional). Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. Specifies whether and how services found in this dependency are used (default is "none"). Specifying a value of "import" for this attribute is equivalent to adding a filter at the end of the import filter list which includes the META-INF/services path from the dependency module. Setting a value of "export" for this attribute is equivalent to the same action on the export filter list. Specifies whether this dependency is optional (defaults to false). An optional dependency will not cause the module to fail to load if not found; however if the module is added later, it will not be retroactively linked into this module's dependency list. The list of paths which are applicable for this system dependency. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. The requested behavior for service handling on a dependency. Do not import or export services from this dependency. Import, but do not re-export, services from this dependency. Import and re-export services found in this dependency. A class name. The class name. A filesystem path name. The path name. A list of zero or more resource roots for this deployment. A resource root within this deployment. A resource root within a deployment. A path filter specification for this resource root (optional). By default all paths are accepted. The name of this resource root (optional). If not specified, defaults to the value of the path attribute. The path of this resource root, relative to the path in which the module.xml file is found. A filter specification, consisting of zero or more filter items. A path to include. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A path to exclude. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A set of literal path names to include. Wildcards are not supported. A set of literal path names to exclude. Wildcards are not supported. A path specification type, which may include wildcards. The path name, which can be a literal path name or it may include the special wildcards "*", "**", and "?". A set of literal path names which can be used for efficient matching against multiple possible values. The path name to include in the set. A module alias type, which defines the target for a module alias. The name of this module alias (required). The version slot of this module alias (optional). The name of the module to which this alias refers (required). The version slot of the module to which this alias refers (optional). An explicitly absent module. The name of the absent module (required). The version slot of the absent module (optional). A property in this property list. The property name as a string (required). The property value (optional, defaults to "true"). A list of permissions that this module requires. The permission to grant. The qualified class name of the permission to grant. The permission name to provide to the permission class constructor. The (optional) list of actions, required by some permission types. jboss-modules-1.4.4.Final/src/main/resources/schema/module-1_3.xsd000077500000000000000000000704341257205723500247330ustar00rootroot00000000000000 Root element for a module declaration. Root element for a module alias declaration. Root element for an absent module. The module declaration type; contains dependencies, resources, and the main class specification. Lists filter expressions to apply to the export filter of the local resources of this module (optional). By default, everything is exported. If filter expressions are provided, the default action is to accept all paths if no filters match. Lists the dependencies of this module (optional). Lists the resource roots of this module (optional). Specifies the main class of this module; used to run the module from the command-line (optional). Lists the user-defined properties to be associated with this module (optional). Lists the requested permission set for this module. If the requested permissions cannot be assigned, the module cannot be loaded. The name of this module (required). The version slot of this module (optional). A module name, which consists of one or more dot (.)-separated segments. Each segment must begin and end with an alphanumeric or underscore (_), and may otherwise contain alphanumerics, underscores, and hyphens (-). A module version slot. A slot may consist of one or more alphanumerics, hyphens (-), underscores (_), plus signs (+), asterisks (*), or dots (.). A list of zero or more module dependencies. A specified module dependency. A dependency on the system (or embedding) class loader. A single module dependency expression. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. A filter used to restrict what packages or directories from this dependency are visible to this module. See also the "services" attribute. The default action of this filter list is to reject a path if not matched. The dependency module name (required). The dependency module version slot (optional). Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. Specifies whether and how services found in this dependency are used (default is "none"). Specifying a value of "import" for this attribute is equivalent to adding a filter at the end of the import filter list which includes the META-INF/services path from the dependency module. Setting a value of "export" for this attribute is equivalent to the same action on the export filter list. Specifies whether this dependency is optional (defaults to false). An optional dependency will not cause the module to fail to load if not found; however if the module is added later, it will not be retroactively linked into this module's dependency list. The list of paths which are applicable for this system dependency. A filter used to restrict what packages or directories from this dependency are re-exported by this module. See also the "export" and "services" attributes. The default action of this filter list is controlled by the value of the "export" attribute. Regardless of the setting of these attributes, this filter always behaves as if it has a final entry which rejects META-INF and all of its subdirectories. Specifies whether this module dependency is re-exported by default (default is "false"). Setting this attribute to true sets the default action for the export filter list to "accept"; leaving it as false sets the default action to "reject". Thus you can still export dependency resources even if this attribute is false by listing explicit paths for the export list. The requested behavior for service handling on a dependency. Do not import or export services from this dependency. Import, but do not re-export, services from this dependency. Import and re-export services found in this dependency. A class name. The class name. A filesystem path name. The path name. A list of zero or more resource roots for this deployment. A resource root within this deployment. A maven artifact within this deployment. A maven native artifact within this deployment. This is a jar that contains a lib/ directory with corresponding platform directories and binaries. This element will cause the jar to be unzipped within the artifact's local repository directory. A maven artifact within a deployment. URI that points to the maven artifact "group:artifact:version[:classifier]" A resource root within a deployment. A path filter specification for this resource root (optional). By default all paths are accepted. The name of this resource root (optional). If not specified, defaults to the value of the path attribute. The path of this resource root, relative to the path in which the module.xml file is found. A filter specification, consisting of zero or more filter items. A path to include. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A path to exclude. The path value can be a path name or a "glob" which may include the special wildcards "*", "**", and "?". A set of literal path names to include. Wildcards are not supported. A set of literal path names to exclude. Wildcards are not supported. A path specification type, which may include wildcards. The path name, which can be a literal path name or it may include the special wildcards "*", "**", and "?". A set of literal path names which can be used for efficient matching against multiple possible values. The path name to include in the set. A module alias type, which defines the target for a module alias. The name of this module alias (required). The version slot of this module alias (optional). The name of the module to which this alias refers (required). The version slot of the module to which this alias refers (optional). An explicitly absent module. The name of the absent module (required). The version slot of the absent module (optional). A property in this property list. The property name as a string (required). The property value (optional, defaults to "true"). A list of permissions that this module requires. The permission to grant. The qualified class name of the permission to grant. The permission name to provide to the permission class constructor. The (optional) list of actions, required by some permission types. jboss-modules-1.4.4.Final/src/test/000077500000000000000000000000001257205723500171145ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/000077500000000000000000000000001257205723500200355ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/000077500000000000000000000000001257205723500206245ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/000077500000000000000000000000001257205723500217445ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/000077500000000000000000000000001257205723500234145ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/AbstractModuleTestCase.java000066400000000000000000000060571257205723500306340ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.log.StreamModuleLogger; import org.jboss.modules.util.Util; import org.junit.BeforeClass; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Abstract Test Case used as a base for all module tests. * * @author John Bailey */ public class AbstractModuleTestCase { protected static final ModuleIdentifier MODULE_ID = ModuleIdentifier.fromString("test.test"); @BeforeClass public static void initUrlHandler() { // this also kicks off Module's static init Module.setModuleLogger(new StreamModuleLogger(System.err)); } protected File getResource(final String path) throws Exception { return Util.getResourceFile(getClass(), path); } protected void copyResource(final String inputResource, final String outputBase, final String outputPath) throws Exception { final File resource = getResource(inputResource); final File outputDirectory = new File(getResource(outputBase), outputPath); if(!resource.exists()) throw new IllegalArgumentException("Resource does not exist"); if (outputDirectory.exists() && outputDirectory.isFile()) throw new IllegalArgumentException("OutputDirectory must be a directory"); if (!outputDirectory.exists()) { if (!outputDirectory.mkdirs()) throw new RuntimeException("Failed to create output directory"); } final File outputFile = new File(outputDirectory, resource.getName()); final InputStream in = new FileInputStream(resource); try { final OutputStream out = new FileOutputStream(outputFile); try { final byte[] b = new byte[8192]; int c; while ((c = in.read(b)) != -1) { out.write(b, 0, c); } out.close(); in.close(); } finally { safeClose(out); } } finally { safeClose(in); } } private static void safeClose(final Closeable closeable) { if (closeable != null) try { closeable.close(); } catch (IOException e) { // meh } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/AbstractResourceLoaderTestCase.java000066400000000000000000000152051257205723500323200ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static org.jboss.modules.util.Util.readBytes; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.junit.Before; import org.junit.Test; /** * Abstract Test Case used as the base for all resource loader tests. * * @author John Bailey */ public abstract class AbstractResourceLoaderTestCase extends AbstractModuleTestCase { protected ResourceLoader loader; @Before public void setupLoader() throws Exception { loader = createLoader(PathFilters.acceptAll()); } protected abstract ResourceLoader createLoader(final PathFilter exportFilter) throws Exception; protected abstract void assertResource(final Resource resource, final String fileName); @Test public void testBasicResource() throws Exception { Resource resource = loader.getResource("/test.txt"); assertNotNull(resource); assertResource(resource, "test.txt"); resource = loader.getResource("/nested/nested.txt"); assertNotNull(resource); assertResource(resource, "nested/nested.txt"); } @Test public void testMissingResource() throws Exception { Resource resource = loader.getResource("/test-bogus.txt"); assertNull(resource); } @Test public void testIndexPaths() throws Exception { final Collection paths = loader.getPaths(); assertFalse(paths.isEmpty()); assertTrue(paths.contains("")); assertTrue(paths.contains("META-INF")); assertTrue(paths.contains("nested")); assertTrue(paths.contains("org")); assertTrue(paths.contains("org/jboss")); assertTrue(paths.contains("org/jboss/modules")); assertTrue(paths.contains("org/jboss/modules/test")); } @Test public void testGetClassSpec() throws Exception { ClassSpec spec = loader.getClassSpec(Module.fileNameOfClass("org.jboss.modules.test.TestClass")); assertNotNull(spec); byte[] bytes = spec.getBytes(); final URL classResource = getClass().getClassLoader().getResource("org/jboss/modules/test/TestClass.class"); final byte[] expectedBytes = readBytes(classResource.openStream()); assertArrayEquals(expectedBytes, bytes); } @Test public void testMissingClassSpec() throws Exception { ClassSpec spec = loader.getClassSpec(Module.fileNameOfClass("org.jboss.modules.test.BogusClass")); assertNull(spec); } @Test public void testGetPackageSpec() throws Exception { PackageSpec spec = loader.getPackageSpec("org.jboss.modules.test"); assertNotNull(spec); assertEquals("JBoss Modules Test Classes", spec.getSpecTitle()); assertEquals("0.1", spec.getSpecVersion()); assertEquals("JBoss", spec.getSpecVendor()); assertEquals("org.jboss.modules.test", spec.getImplTitle()); assertEquals("1.0", spec.getImplVersion()); assertEquals("JBoss", spec.getImplVendor()); } @Test public void testMissingPackageSpec() throws Exception { PackageSpec spec = loader.getPackageSpec("org.jboss.modules.bogus"); assertNotNull(spec); assertEquals("MODULES-89", spec.getSpecTitle()); assertNull(spec.getSpecVersion()); assertNull(spec.getSpecVendor()); assertNull(spec.getImplTitle()); assertNull(spec.getImplVersion()); assertNull(spec.getImplVendor()); } @Test public void testIterateResourcesRootRecursive() throws Exception { Set expected = new HashSet(); expected.add("test.txt"); expected.add("nested/nested.txt"); expected.add("org/jboss/modules/test/TestClass.class"); expected.add("META-INF/MANIFEST.MF"); assertEquals(expected, getResourceNames("/", true)); assertEquals(expected, getResourceNames("", true)); } @Test public void testIterateResourcesRoot() throws Exception { Set expected = new HashSet(); expected.add("test.txt"); assertEquals(expected, getResourceNames("/", false)); assertEquals(expected, getResourceNames("", false)); } @Test public void testIterateResourcesNested() throws Exception { Set expected = new HashSet(); expected.add("nested/nested.txt"); assertEquals(expected, getResourceNames("/nested", true)); assertEquals(expected, getResourceNames("/nested", false)); assertEquals(expected, getResourceNames("nested", true)); assertEquals(expected, getResourceNames("nested", false)); } @Test public void testIterateResourcesClasses() throws Exception { Set expected = new HashSet(); expected.add("org/jboss/modules/test/TestClass.class"); assertEquals(expected, getResourceNames("/org/jboss/modules", true)); assertEquals(expected, getResourceNames("org/jboss/modules", true)); expected = Collections.emptySet(); assertEquals(expected, getResourceNames("/org/jboss/modules", false)); assertEquals(expected, getResourceNames("org/jboss/modules", false)); } private Set getResourceNames(String startPath, boolean recursive) { Set result = new HashSet(); IterableResourceLoader itloader = (IterableResourceLoader) loader; Iterator itres = itloader.iterateResources(startPath, recursive); while(itres.hasNext()) { result.add(itres.next().getName()); } return result; } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ClassFilteringTest.java000066400000000000000000000105151257205723500300320ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.ClassFilter; import org.jboss.modules.filter.ClassFilters; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.test.BarImpl; import org.jboss.modules.test.QuxBar; import org.jboss.modules.test.QuxFoo; import org.jboss.modules.test.QuxImpl; import org.jboss.modules.util.ModulesTestBase; import org.jboss.modules.util.TestResourceLoader; import org.junit.Test; import static org.jboss.modules.DependencySpec.createLocalDependencySpec; import static org.jboss.modules.DependencySpec.createModuleDependencySpec; import static org.jboss.modules.ResourceLoaderSpec.createResourceLoaderSpec; import static org.jboss.modules.util.TestResourceLoader.TestResourceLoaderBuilder; /** * [MODULES-69] Allow for OSGi style Class Filtering * * @author Thomas.Diesler@jboss.com * @since 28-Apr-2011 */ public class ClassFilteringTest extends ModulesTestBase { @Test public void testClassFilter() throws Exception { final ModuleIdentifier identifierA = ModuleIdentifier.create(getClass().getSimpleName()); ModuleSpec.Builder specBuilderA = ModuleSpec.build(identifierA); // Export-Package: com.acme.foo; include:="Qux*,BarImpl";exclude:=QuxImpl String packagePath = QuxBar.class.getPackage().getName().replace('.', '/'); PathFilter inA = PathFilters.match(packagePath + "/Qux*.class"); PathFilter inB = PathFilters.match(packagePath + "/BarImpl.class"); PathFilter exA = PathFilters.match(packagePath + "/QuxImpl.class"); //A class is only visible if it is: // Matched with an entry in the included list, and // Not matched with an entry in the excluded list. PathFilter in = PathFilters.any(inA, inB); PathFilter ex = PathFilters.not(PathFilters.any(exA)); final PathFilter filter = PathFilters.all(in, ex); ClassFilter classImportFilter = ClassFilters.acceptAll(); ClassFilter classExportFilter = ClassFilters.fromResourcePathFilter(filter); specBuilderA.addResourceRoot(createResourceLoaderSpec(getTestResourceLoader())); PathFilter importFilter = PathFilters.acceptAll(); PathFilter exportFilter = PathFilters.acceptAll(); PathFilter resourceImportFilter = PathFilters.acceptAll(); PathFilter resourceExportFilter = PathFilters.acceptAll(); specBuilderA.addDependency(createLocalDependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter)); addModuleSpec(specBuilderA.create()); ModuleIdentifier identifierB = ModuleIdentifier.create("moduleB"); ModuleSpec.Builder specBuilderB = ModuleSpec.build(identifierB); specBuilderB.addDependency(createModuleDependencySpec(identifierA)); addModuleSpec(specBuilderB.create()); assertLoadClass(identifierA, QuxFoo.class.getName()); assertLoadClass(identifierA, QuxBar.class.getName()); assertLoadClass(identifierA, QuxImpl.class.getName()); assertLoadClass(identifierA, BarImpl.class.getName()); assertLoadClass(identifierB, QuxFoo.class.getName()); assertLoadClass(identifierB, QuxBar.class.getName()); assertLoadClassFail(identifierB, QuxImpl.class.getName()); assertLoadClass(identifierB, BarImpl.class.getName()); } private TestResourceLoader getTestResourceLoader() throws Exception { TestResourceLoaderBuilder builder = new TestResourceLoaderBuilder(); builder.addClasses(QuxBar.class, QuxFoo.class, QuxImpl.class, BarImpl.class); return builder.create(); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ClassPathModuleLoaderTest.java000066400000000000000000000077101257205723500313030ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.lang.reflect.Method; import org.junit.BeforeClass; import org.junit.Test; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * Test to verify the functionality of the ClassPathModuleLoader. * * @author @author James R. Perkins * @author Scott Stark (sstark@redhat.com) */ public class ClassPathModuleLoaderTest extends AbstractModuleTestCase { @BeforeClass public static void beforeClass() throws Exception { final Method method = ModuleLoader.class.getDeclaredMethod("installMBeanServer"); method.setAccessible(true); method.invoke(null); } @Test public void testLoader() throws Exception { final File repoRoot = getResource("test/repo"); final String classPath = "./target/test-classes/test/repo"; final String deps = "test.test,test.with-deps"; final String mainClass = "org.jboss.modules.test.TestClass"; final ModuleLoader moduleLoader = new ClassPathModuleLoader(new LocalModuleLoader(new File[] { repoRoot }), mainClass, classPath, deps); Module module = moduleLoader.loadModule(ModuleIdentifier.CLASSPATH); module.getClassLoader(); assertNotNull(module); } /** * I need to be able to load EJBContainerProvider from a dependency. * * @author Carlo de Wolf */ @Test public void testService() throws Exception { final File repoRoot = getResource("test/repo"); final String classPath = "./target/test-classes/test/repo"; final String deps = "test.service"; final String mainClass = null; final ModuleLoader moduleLoader = new ClassPathModuleLoader(new LocalModuleLoader(new File[] { repoRoot }), mainClass, classPath, deps); final Module module = moduleLoader.loadModule(ModuleIdentifier.CLASSPATH); final ClassLoader classLoader = module.getClassLoader(); final URL url = classLoader.getResource("META-INF/services/dummy"); assertNotNull(url); } /** * Validate that dependent module META-INF/services/* content is seen * @throws Exception */ @Test public void testMultipleServices() throws Exception { final File repoRoot = getResource("test/repo"); final String classPath = "./target/test-classes/test/repo"; final String deps = "test.jaxrs"; final String mainClass = null; final ModuleLoader moduleLoader = new ClassPathModuleLoader(new LocalModuleLoader(new File[] { repoRoot }), mainClass, classPath, deps); final Module module = moduleLoader.loadModule(ModuleIdentifier.CLASSPATH); final ClassLoader classLoader = module.getClassLoader(); final Enumeration services = classLoader.getResources("META-INF/services/javax.ws.rs.ext.Providers"); assertNotNull(services); ArrayList found = new ArrayList(); while(services.hasMoreElements()) { found.add(services.nextElement()); } assertEquals("Found 2 services of type javax.ws.rs.ext.Providers", 2, found.size()); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ConcurrentClassLoaderTest.java000066400000000000000000000122001257205723500313510ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.test.ClassA; import org.jboss.modules.test.ClassB; import org.jboss.modules.test.ClassC; import org.jboss.modules.test.ClassD; import org.jboss.modules.util.Util; import org.junit.Test; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; /** * Test case to verify the concurrent classloader base correctly handles common concurrency issues with classloading.. * * @author John E. Bailey */ public class ConcurrentClassLoaderTest { volatile Throwable threadOneProblem; volatile Throwable threadTwoProblem; @Test public void testClassLoadingDeadlockAvoidance() throws Throwable { /* Uncomment the following lines to demonstrate a deadlock that occurs with normal classloader delegation */ //final DeadLockingLoader classLoaderOne = new DeadLockingLoader(ConcurrentClassLoaderTest.class.getClassLoader(), Arrays.asList(ClassA.class.getName(), ClassD.class.getName())); //final DeadLockingLoader classLoaderTwo = new DeadLockingLoader(ConcurrentClassLoaderTest.class.getClassLoader(), Arrays.asList(ClassB.class.getName(), ClassC.class.getName())); final TestConcurrentClassLoader classLoaderOne = new TestConcurrentClassLoader(ConcurrentClassLoaderTest.class.getClassLoader(), Arrays.asList(ClassA.class.getName(), ClassD.class.getName())); final TestConcurrentClassLoader classLoaderTwo = new TestConcurrentClassLoader(ConcurrentClassLoaderTest.class.getClassLoader(), Arrays.asList(ClassB.class.getName(), ClassC.class.getName())); classLoaderOne.delegate = classLoaderTwo; classLoaderTwo.delegate = classLoaderOne; final CountDownLatch latch = new CountDownLatch(1); final Thread threadOne = new Thread(new Runnable() { @Override public void run() { try { latch.await(); classLoaderOne.loadClass(ClassA.class.getName()); } catch (Throwable t) { threadOneProblem = t; } } }); final Thread threadTwo = new Thread(new Runnable() { @Override public void run() { try { latch.await(); classLoaderTwo.loadClass(ClassC.class.getName()); } catch (Throwable t) { threadTwoProblem = t; } } }); threadOne.start(); threadTwo.start(); latch.countDown(); threadOne.join(); threadTwo.join(); if (threadOneProblem != null) throw threadOneProblem; if (threadTwoProblem != null) throw threadTwoProblem; } private static final class TestConcurrentClassLoader extends ConcurrentClassLoader { static { boolean parallelOk = true; try { parallelOk = ClassLoader.registerAsParallelCapable(); } catch (Throwable ignored) { } if (! parallelOk) { throw new Error("Failed to register " + TestConcurrentClassLoader.class.getName() + " as parallel-capable"); } } private final ClassLoader realLoader; private final Set allowedClasses = new HashSet(); private ClassLoader delegate; private TestConcurrentClassLoader(final ClassLoader realLoader, final Collection allowedClasses) { this.realLoader = realLoader; this.allowedClasses.addAll(allowedClasses); } @Override protected Class findClass(String className, boolean exportsOnly, final boolean resolve) throws ClassNotFoundException { Class c = findLoadedClass(className); if(c == null && className.startsWith("java")) c = findSystemClass(className); if(c == null && allowedClasses.contains(className)) { try { final byte[] classBytes = Util.getClassBytes(realLoader.loadClass(className)); c = defineClass(className, classBytes, 0, classBytes.length); } catch(Throwable t) { throw new ClassNotFoundException("Failed to load class " + className, t); } } if(c == null) c = delegate.loadClass(className); return c; } }; } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ErrorHandlingTest.java000066400000000000000000000042571257205723500276650ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.test.ClassA; import org.jboss.modules.util.TestModuleLoader; import org.jboss.modules.util.TestResourceLoader; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.fail; /** * @author Carlo de Wolf */ public class ErrorHandlingTest extends AbstractModuleTestCase { private static final ModuleIdentifier MODULE_A = ModuleIdentifier.fromString("test-module-a"); private TestModuleLoader moduleLoader; @Before public void before() throws Exception { moduleLoader = new TestModuleLoader(); final ModuleSpec.Builder moduleABuilder = ModuleSpec.build(MODULE_A); moduleABuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(ClassA.class) .create()) ); moduleABuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleABuilder.create()); } @Test public void testNonLinkingClass() throws ModuleLoadException, ClassNotFoundException { final Module module = moduleLoader.loadModule(MODULE_A); final ClassLoader classLoader = module.getClassLoader(); try { classLoader.loadClass(ClassA.class.getName()); fail("Should have thrown a LinkageError"); } catch(LinkageError e) { // good } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/FileResourceLoaderTest.java000066400000000000000000000035631257205723500306440ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.PathFilter; import org.junit.Assert; import java.io.File; import java.security.AccessController; /** * Test the functionality of the FileResourceLoader * * @author John Bailey */ public class FileResourceLoaderTest extends AbstractResourceLoaderTestCase { private File resourceRoot; protected ResourceLoader createLoader(final PathFilter exportFilter) throws Exception { resourceRoot = getResource("test/fileresourceloader"); // Copy the classfile over copyResource("org/jboss/modules/test/TestClass.class", "test/fileresourceloader", "org/jboss/modules/test"); return new FileResourceLoader("test-root", resourceRoot, AccessController.getContext()); } @Override protected void assertResource(Resource resource, String fileName) { final File resourceFile = getExpectedFile(fileName); Assert.assertEquals(resourceFile.length(), resource.getSize()); } public void testGetClassSpec() throws Exception { super.testGetClassSpec(); } protected File getExpectedFile(String fileName) { return new File(resourceRoot, fileName); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/InstantiatePrivateAccessTest.java000066400000000000000000000044131257205723500320610ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.security.AllPermission; import java.security.Permissions; import org.jboss.modules.security.ModularPermissionFactory; import org.junit.Test; /** * @author David M. Lloyd */ public class InstantiatePrivateAccessTest { @Test public void ensureFailure() { try { Module.getPrivateAccess(); fail("Expected security exception"); } catch (SecurityException ok) {} } @Test public void ensureModularPermissionFactory() { final ModuleIdentifier test = ModuleIdentifier.create("test"); final ModuleLoader moduleLoader = new ModuleLoader(new ModuleFinder[]{ new ModuleFinder() { public ModuleSpec findModule(final ModuleIdentifier identifier, final ModuleLoader delegateLoader) throws ModuleLoadException { if (identifier.equals(test)) { final Permissions perms = new Permissions(); perms.add(new AllPermission()); return ModuleSpec.build(test).setPermissionCollection(perms).create(); } else { return null; } } } }); final ModularPermissionFactory factory = new ModularPermissionFactory(moduleLoader, test, RuntimePermission.class.getName(), "foo", "*"); assertEquals(new RuntimePermission("foo", "*"), factory.construct()); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/JAXPModuleTest.java000066400000000000000000001271701257205723500270370ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import java.util.Properties; import javax.xml.XMLConstants; import javax.xml.datatype.DatatypeConstants.Field; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.EventFilter; import javax.xml.stream.Location; import javax.xml.stream.StreamFilter; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLReporter; import javax.xml.stream.XMLResolver; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.Comment; import javax.xml.stream.events.DTD; import javax.xml.stream.events.EndDocument; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.EntityDeclaration; import javax.xml.stream.events.EntityReference; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.ProcessingInstruction; import javax.xml.stream.events.StartDocument; import javax.xml.stream.events.StartElement; import javax.xml.stream.util.XMLEventAllocator; import javax.xml.transform.ErrorListener; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TemplatesHandler; import javax.xml.transform.sax.TransformerHandler; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import javax.xml.validation.ValidatorHandler; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactoryConfigurationException; import javax.xml.xpath.XPathFunctionResolver; import javax.xml.xpath.XPathVariableResolver; import __redirected.__SchemaFactory; import __redirected.__XMLReaderFactory; import __redirected.__XPathFactory; import __redirected.__DatatypeFactory; import __redirected.__DocumentBuilderFactory; import __redirected.__JAXPRedirected; import __redirected.__SAXParserFactory; import __redirected.__TransformerFactory; import __redirected.__XMLEventFactory; import __redirected.__XMLInputFactory; import __redirected.__XMLOutputFactory; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.test.JAXPCaller; import org.jboss.modules.util.TestModuleLoader; import org.jboss.modules.util.TestResourceLoader; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.ls.LSResourceResolver; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLFilter; import org.xml.sax.XMLReader; /** * Tests JAXP, including all of the possible ways to trigger redirection * * @author Jason T. Greene */ @SuppressWarnings("deprecation") public class JAXPModuleTest extends AbstractModuleTestCase { private static final ModuleIdentifier FAKE_JAXP = ModuleIdentifier.fromString("fake-jaxp"); private TestModuleLoader moduleLoader; private PathFilter jdkApiFilter; @Before public void setupModuleLoader() throws Exception { jdkApiFilter = PathFilters.any(PathFilters.match("javax/**"), PathFilters.match("org/w3c/**"), PathFilters.match("org/xml/**")); moduleLoader = new TestModuleLoader(); ModuleSpec.Builder moduleWithContentBuilder = ModuleSpec.build(ModuleIdentifier.fromString("test-jaxp")); moduleWithContentBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(JAXPCaller.class) .create() )); moduleWithContentBuilder.addDependency(DependencySpec.createSystemDependencySpec(JDKPaths.JDK)); moduleWithContentBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleWithContentBuilder.setMainClass(JAXPCaller.class.getName()); moduleLoader.addModuleSpec(moduleWithContentBuilder.create()); moduleWithContentBuilder = ModuleSpec.build(FAKE_JAXP); moduleWithContentBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(FakeSAXParserFactory.class) .addClass(FakeSAXParser.class) .addClass(FakeDocumentBuilderFactory.class) .addClass(FakeDocumentBuilder.class) .addClass(FakeTransformerFactory.class) .addClass(FakeTransformer.class) .addClass(FakeTransformerHandler.class) .addClass(FakeXMLEventFactory.class) .addClass(FakeDTD.class) .addClass(FakeXMLInputFactory.class) .addClass(FakeXMLOutputFactory.class) .addClass(FakeDatatypeFactory.class) .addClass(FakeDuration.class) .addClass(FakeXPathFactory.class) .addClass(FakeXPath.class) .addClass(FakeSchemaFactory.class) .addClass(FakeSchema.class) .addClass(FakeXMLReader.class) .addResources(getResource("test/modulecontentloader/jaxp")) .create() )); moduleWithContentBuilder.addDependency(DependencySpec.createSystemDependencySpec(jdkApiFilter, PathFilters.rejectAll(), JDKPaths.JDK)); moduleWithContentBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithContentBuilder.create()); moduleWithContentBuilder = ModuleSpec.build(ModuleIdentifier.fromString("test-jaxp-import")); moduleWithContentBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(JAXPCaller.class) .create() )); moduleWithContentBuilder.addDependency(DependencySpec.createSystemDependencySpec(jdkApiFilter, PathFilters.rejectAll(), JDKPaths.JDK)); moduleWithContentBuilder.addDependency(DependencySpec.createModuleDependencySpec(PathFilters.acceptAll(), PathFilters.rejectAll(), moduleLoader, FAKE_JAXP, false)); moduleWithContentBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithContentBuilder.create()); } @SuppressWarnings("unchecked") private static T invokeMethod(Object obj, String method) { try { return (T) obj.getClass().getMethod(method).invoke(obj); } catch (Exception e) { throw new IllegalStateException(e); } } @Test public void testJVMDefault() throws Exception { ModuleClassLoader cl = moduleLoader.loadModule(ModuleIdentifier.fromString("test-jaxp")).getClassLoader(); ClassLoader old = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(cl); Class clazz = cl.loadClass("org.jboss.modules.test.JAXPCaller"); checkDom(clazz, false); checkSax(clazz, false); checkTransformer(clazz, false); checkSAXTransformer(clazz, false); checkXPath(clazz, false); checkXmlEvent(clazz, false); checkXmlInput(clazz, false); checkXmlOutput(clazz, false); checkDatatype(clazz, false); checkSchema(clazz, false); checkXMLReader(clazz, false); } finally { Thread.currentThread().setContextClassLoader(old); } } @Test public void testReplaceDefault() throws Exception { __JAXPRedirected.changeAll(FAKE_JAXP, moduleLoader); ModuleClassLoader cl = moduleLoader.loadModule(ModuleIdentifier.fromString("test-jaxp")).getClassLoader(); Class clazz = cl.loadClass("org.jboss.modules.test.JAXPCaller"); ClassLoader old = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(cl); checkDom(clazz, true); checkSax(clazz, true); checkTransformer(clazz, true); checkSAXTransformer(clazz, true); checkXPath(clazz, true); checkXmlEvent(clazz, true); checkXmlInput(clazz, true); checkXmlOutput(clazz, true); checkDatatype(clazz, true); checkSchema(clazz, true); checkXMLReader(clazz, true); } finally { Thread.currentThread().setContextClassLoader(old); __JAXPRedirected.restorePlatformFactory(); } } @Test public void testImport() throws Exception { ModuleClassLoader cl = moduleLoader.loadModule(ModuleIdentifier.fromString("test-jaxp-import")).getClassLoader(); Class clazz = cl.loadClass("org.jboss.modules.test.JAXPCaller"); ClassLoader old = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(cl); checkDom(clazz, true); checkSax(clazz, true); checkTransformer(clazz, true); checkSAXTransformer(clazz, true); checkXPath(clazz, true); checkXmlEvent(clazz, true); checkXmlInput(clazz, true); checkXmlOutput(clazz, true); checkDatatype(clazz, true); checkSchema(clazz, true); checkXMLReader(clazz, true); } finally { Thread.currentThread().setContextClassLoader(old); } } /* * This test is slightly dangerous. If it causes problems, just add @Ignore * and/or let me know. * -Jason */ @Test public void testMain() throws Throwable { java.lang.reflect.Field field = DefaultBootModuleLoaderHolder.class.getDeclaredField("INSTANCE"); java.lang.reflect.Field modifiersField = java.lang.reflect.Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.setAccessible(true); ModuleLoader oldMl = (ModuleLoader) field.get(null); field.set(null, moduleLoader); Main.main(new String[] {"-jaxpmodule", "fake-jaxp", "test-jaxp"}); ModuleClassLoader cl = moduleLoader.loadModule(ModuleIdentifier.fromString("test-jaxp")).getClassLoader(); Class clazz = cl.loadClass("org.jboss.modules.test.JAXPCaller"); ClassLoader old = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(cl); checkDom(clazz, true); checkSax(clazz, true); checkTransformer(clazz, true); checkSAXTransformer(clazz, true); checkXmlEvent(clazz, true); checkXPath(clazz, true); checkXmlInput(clazz, true); checkXmlOutput(clazz, true); checkDatatype(clazz, true); checkSchema(clazz, true); checkXMLReader(clazz, true); } finally { field.set(null, oldMl); Thread.currentThread().setContextClassLoader(old); __JAXPRedirected.restorePlatformFactory(); } } public void checkDom(Class clazz, boolean fake) throws Exception { DocumentBuilder builder = invokeMethod(clazz.newInstance(), "documentBuilder"); DocumentBuilderFactory factory = invokeMethod(clazz.newInstance(), "documentFactory"); Assert.assertEquals(__DocumentBuilderFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeDocumentBuilder.class.getName(), builder.getClass().getName()); } else { // Double check that it works Document document = invokeMethod(clazz.newInstance(), "document"); document.createElement("test"); Assert.assertSame(DocumentBuilderFactory.newInstance().newDocumentBuilder().getClass(), builder.getClass()); } } public void checkSax(Class clazz, boolean fake) throws Exception { SAXParser parser = invokeMethod(clazz.newInstance(), "saxParser"); SAXParserFactory factory = invokeMethod(clazz.newInstance(), "saxParserFactory"); Assert.assertEquals(__SAXParserFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeSAXParser.class.getName(), parser.getClass().getName()); } else { Assert.assertSame(SAXParserFactory.newInstance().newSAXParser().getClass(), parser.getClass()); } } public void checkTransformer(Class clazz, boolean fake) throws Exception { Transformer parser = invokeMethod(clazz.newInstance(), "transformer"); TransformerFactory factory = invokeMethod(clazz.newInstance(), "transformerFactory"); Assert.assertEquals(__TransformerFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeTransformer.class.getName(), parser.getClass().getName()); } else { Assert.assertSame(TransformerFactory.newInstance().newTransformer().getClass(), parser.getClass()); } } public void checkXPath(Class clazz, boolean fake) throws Exception { XPath parser = invokeMethod(clazz.newInstance(), "xpath"); XPathFactory factory = invokeMethod(clazz.newInstance(), "xpathFactory"); Assert.assertEquals(__XPathFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeXPath.class.getName(), parser.getClass().getName()); } else { Assert.assertSame(XPathFactory.newInstance().newXPath().getClass(), parser.getClass()); } } public void checkSchema(Class clazz, boolean fake) throws Exception { Schema parser = invokeMethod(clazz.newInstance(), "schema"); SchemaFactory factory = invokeMethod(clazz.newInstance(), "schemaFactory"); Assert.assertEquals(__SchemaFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeSchema.class.getName(), parser.getClass().getName()); } else { Assert.assertSame(SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema().getClass(), parser.getClass()); } } public void checkXMLReader(Class clazz, boolean fake) throws Exception { XMLReader parser = invokeMethod(clazz.newInstance(), "xmlReader"); Assert.assertEquals(__XMLReaderFactory.class.getName(), parser.getClass().getName()); Object test = null; try { test = parser.getProperty("test"); } catch (Exception ignore) { } if (fake) { Assert.assertEquals("fake-fake-fake", test); } else { Assert.assertFalse("fake-fake-fake".equals(test)); } } public void checkSAXTransformer(Class clazz, boolean fake) throws Exception { TransformerHandler transformerHandler = invokeMethod(clazz.newInstance(), "transformerHandler"); TransformerFactory factory = invokeMethod(clazz.newInstance(), "transformerFactory"); Assert.assertEquals(__TransformerFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeTransformerHandler.class.getName(), transformerHandler.getClass().getName()); } else { Assert.assertSame(((SAXTransformerFactory) TransformerFactory.newInstance()).newTransformerHandler().getClass(), transformerHandler.getClass()); } } public void checkXmlEvent(Class clazz, boolean fake) throws Exception { DTD dtd = invokeMethod(clazz.newInstance(), "eventDTD"); XMLEventFactory factory = invokeMethod(clazz.newInstance(), "eventFactory"); Assert.assertEquals(__XMLEventFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(FakeDTD.class.getName(), dtd.getClass().getName()); } else { Assert.assertSame(XMLEventFactory.newInstance().createDTD("blah").getClass(), dtd.getClass()); } } public void checkXmlInput(Class clazz, boolean fake) throws Exception { String property = invokeMethod(clazz.newInstance(), "inputProperty"); XMLInputFactory factory = invokeMethod(clazz.newInstance(), "inputFactory"); Assert.assertEquals(__XMLInputFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(new FakeXMLInputFactory().getProperty("blah"), property); } else { Assert.assertFalse(new FakeXMLInputFactory().getProperty("blah").equals(property)); } } public void checkXmlOutput(Class clazz, boolean fake) throws Exception { String property = invokeMethod(clazz.newInstance(), "outputProperty"); XMLOutputFactory factory = invokeMethod(clazz.newInstance(), "outputFactory"); Assert.assertEquals(__XMLOutputFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(new FakeXMLOutputFactory().getProperty("blah"), property); } else { Assert.assertFalse(new FakeXMLInputFactory().getProperty("blah").equals(property)); } } public void checkDatatype(Class clazz, boolean fake) throws Exception { Duration duration = invokeMethod(clazz.newInstance(), "duration"); DatatypeFactory factory = invokeMethod(clazz.newInstance(), "datatypeFactory"); Assert.assertEquals(__DatatypeFactory.class.getName(), factory.getClass().getName()); if (fake) { Assert.assertEquals(new FakeDuration().getSign(), duration.getSign()); } else { Assert.assertFalse(new FakeDuration().getSign() == duration.getSign()); } } public static class FakeSAXParserFactory extends SAXParserFactory { public SAXParser newSAXParser() throws ParserConfigurationException, SAXException { return new FakeSAXParser(); } public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { } public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { return false; } } public static class FakeSAXParser extends SAXParser { @SuppressWarnings("deprecation") public org.xml.sax.Parser getParser() throws SAXException { return null; } public XMLReader getXMLReader() throws SAXException { return null; } public boolean isNamespaceAware() { return false; } public boolean isValidating() { return false; } public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { } public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return null; } } public static class FakeDocumentBuilderFactory extends DocumentBuilderFactory { public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { return new FakeDocumentBuilder(); } public void setAttribute(String name, Object value) throws IllegalArgumentException { } public Object getAttribute(String name) throws IllegalArgumentException { return null; } public void setFeature(String name, boolean value) throws ParserConfigurationException { } public boolean getFeature(String name) throws ParserConfigurationException { return false; } } public static class FakeDocumentBuilder extends DocumentBuilder { public Document parse(InputSource is) throws SAXException, IOException { return null; } public boolean isNamespaceAware() { return false; } public boolean isValidating() { return false; } public void setEntityResolver(EntityResolver er) { } public void setErrorHandler(ErrorHandler eh) { } public Document newDocument() { return null; } public DOMImplementation getDOMImplementation() { return null; } } public static class FakeTransformerFactory extends SAXTransformerFactory { public Transformer newTransformer(Source source) throws TransformerConfigurationException { return new FakeTransformer(); } public Transformer newTransformer() throws TransformerConfigurationException { return new FakeTransformer(); } public Templates newTemplates(Source source) throws TransformerConfigurationException { return null; } public Source getAssociatedStylesheet(Source source, String media, String title, String charset) throws TransformerConfigurationException { return null; } public void setURIResolver(URIResolver resolver) { } public URIResolver getURIResolver() { return null; } public void setFeature(String name, boolean value) throws TransformerConfigurationException { } public boolean getFeature(String name) { return false; } public void setAttribute(String name, Object value) { } public Object getAttribute(String name) { return null; } public void setErrorListener(ErrorListener listener) { } public ErrorListener getErrorListener() { return null; } public TransformerHandler newTransformerHandler(Source src) throws TransformerConfigurationException { return null; } public TransformerHandler newTransformerHandler(Templates templates) throws TransformerConfigurationException { return null; } public TransformerHandler newTransformerHandler() throws TransformerConfigurationException { return new FakeTransformerHandler(); } public TemplatesHandler newTemplatesHandler() throws TransformerConfigurationException { return null; } public XMLFilter newXMLFilter(Source src) throws TransformerConfigurationException { return null; } public XMLFilter newXMLFilter(Templates templates) throws TransformerConfigurationException { return null; } } private static class FakeTransformerHandler implements TransformerHandler { public void setResult(Result result) throws IllegalArgumentException { } public void setSystemId(String systemID) { } public String getSystemId() { return null; } public Transformer getTransformer() { return null; } public void setDocumentLocator(Locator locator) { } public void startDocument() throws SAXException { } public void endDocument() throws SAXException { } public void startPrefixMapping(String prefix, String uri) throws SAXException { } public void endPrefixMapping(String prefix) throws SAXException { } public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { } public void endElement(String uri, String localName, String qName) throws SAXException { } public void characters(char[] ch, int start, int length) throws SAXException { } public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { } public void processingInstruction(String target, String data) throws SAXException { } public void skippedEntity(String name) throws SAXException { } public void notationDecl(String name, String publicId, String systemId) throws SAXException { } public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException { } public void startDTD(String name, String publicId, String systemId) throws SAXException { } public void endDTD() throws SAXException { } public void startEntity(String name) throws SAXException { } public void endEntity(String name) throws SAXException { } public void startCDATA() throws SAXException { } public void endCDATA() throws SAXException { } public void comment(char[] ch, int start, int length) throws SAXException { } } public static class FakeTransformer extends Transformer { public void transform(Source xmlSource, Result outputTarget) throws TransformerException { } public void setParameter(String name, Object value) { } public Object getParameter(String name) { return null; } public void clearParameters() { } public void setURIResolver(URIResolver resolver) { } public URIResolver getURIResolver() { return null; } public void setOutputProperties(Properties format) { } public Properties getOutputProperties() { return null; } public void setOutputProperty(String name, String value) throws IllegalArgumentException { } public String getOutputProperty(String name) throws IllegalArgumentException { return null; } public void setErrorListener(ErrorListener listener) throws IllegalArgumentException { } public ErrorListener getErrorListener() { return null; } } public static class FakeXMLEventFactory extends XMLEventFactory { public void setLocation(Location location) { } public Attribute createAttribute(String prefix, String namespaceURI, String localName, String value) { return null; } public Attribute createAttribute(String localName, String value) { return null; } public Attribute createAttribute(QName name, String value) { return null; } public Namespace createNamespace(String namespaceURI) { return null; } public Namespace createNamespace(String prefix, String namespaceUri) { return null; } public StartElement createStartElement(QName name, Iterator attributes, Iterator namespaces) { return null; } public StartElement createStartElement(String prefix, String namespaceUri, String localName) { return null; } public StartElement createStartElement(String prefix, String namespaceUri, String localName, Iterator attributes, Iterator namespaces) { return null; } public StartElement createStartElement(String prefix, String namespaceUri, String localName, Iterator attributes, Iterator namespaces, NamespaceContext context) { return null; } public EndElement createEndElement(QName name, Iterator namespaces) { return null; } public EndElement createEndElement(String prefix, String namespaceUri, String localName) { return null; } public EndElement createEndElement(String prefix, String namespaceUri, String localName, Iterator namespaces) { return null; } public Characters createCharacters(String content) { return null; } public Characters createCData(String content) { return null; } public Characters createSpace(String content) { return null; } public Characters createIgnorableSpace(String content) { return null; } public StartDocument createStartDocument() { return null; } public StartDocument createStartDocument(String encoding, String version, boolean standalone) { return null; } public StartDocument createStartDocument(String encoding, String version) { return null; } public StartDocument createStartDocument(String encoding) { return null; } public EndDocument createEndDocument() { return null; } public EntityReference createEntityReference(String name, EntityDeclaration declaration) { return null; } public Comment createComment(String text) { return null; } public ProcessingInstruction createProcessingInstruction(String target, String data) { return null; } public DTD createDTD(String dtd) { return new FakeDTD(); } } public static class FakeDTD implements DTD { public int getEventType() { return 0; } public Location getLocation() { return null; } public boolean isStartElement() { return false; } public boolean isAttribute() { return false; } public boolean isNamespace() { return false; } public boolean isEndElement() { return false; } public boolean isEntityReference() { return false; } public boolean isProcessingInstruction() { return false; } public boolean isCharacters() { return false; } public boolean isStartDocument() { return false; } public boolean isEndDocument() { return false; } public StartElement asStartElement() { return null; } public EndElement asEndElement() { return null; } public Characters asCharacters() { return null; } public QName getSchemaType() { return null; } public void writeAsEncodedUnicode(Writer writer) throws XMLStreamException { } public String getDocumentTypeDeclaration() { return null; } public Object getProcessedDTD() { return null; } public List getNotations() { return null; } public List getEntities() { return null; } } public static class FakeXMLInputFactory extends XMLInputFactory { public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException { return null; } public XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException { return null; } public XMLStreamReader createXMLStreamReader(InputStream stream) throws XMLStreamException { return null; } public XMLStreamReader createXMLStreamReader(InputStream stream, String encoding) throws XMLStreamException { return null; } public XMLStreamReader createXMLStreamReader(String systemId, InputStream stream) throws XMLStreamException { return null; } public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(Reader reader) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(String systemId, Reader reader) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(XMLStreamReader reader) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(Source source) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(InputStream stream) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(InputStream stream, String encoding) throws XMLStreamException { return null; } public XMLEventReader createXMLEventReader(String systemId, InputStream stream) throws XMLStreamException { return null; } public XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter) throws XMLStreamException { return null; } public XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter) throws XMLStreamException { return null; } public XMLResolver getXMLResolver() { return null; } public void setXMLResolver(XMLResolver resolver) { } public XMLReporter getXMLReporter() { return null; } public void setXMLReporter(XMLReporter reporter) { } public void setProperty(String name, Object value) throws IllegalArgumentException { } public Object getProperty(String name) throws IllegalArgumentException { return "magic-fake-thing"; } public boolean isPropertySupported(String name) { return false; } public void setEventAllocator(XMLEventAllocator allocator) { } public XMLEventAllocator getEventAllocator() { return null; } } public static class FakeXMLOutputFactory extends XMLOutputFactory { public XMLStreamWriter createXMLStreamWriter(Writer stream) throws XMLStreamException { return null; } public XMLStreamWriter createXMLStreamWriter(OutputStream stream) throws XMLStreamException { return null; } public XMLStreamWriter createXMLStreamWriter(OutputStream stream, String encoding) throws XMLStreamException { return null; } public XMLStreamWriter createXMLStreamWriter(Result result) throws XMLStreamException { return null; } public XMLEventWriter createXMLEventWriter(Result result) throws XMLStreamException { return null; } public XMLEventWriter createXMLEventWriter(OutputStream stream) throws XMLStreamException { return null; } public XMLEventWriter createXMLEventWriter(OutputStream stream, String encoding) throws XMLStreamException { return null; } public XMLEventWriter createXMLEventWriter(Writer stream) throws XMLStreamException { return null; } public void setProperty(String name, Object value) throws IllegalArgumentException { } public Object getProperty(String name) throws IllegalArgumentException { return "magic-fake-thing"; } public boolean isPropertySupported(String name) { return false; } } public static class FakeDatatypeFactory extends DatatypeFactory { public Duration newDuration(String lexicalRepresentation) { return null; } public Duration newDuration(long durationInMilliSeconds) { return new FakeDuration(); } public Duration newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes, BigDecimal seconds) { return null; } public XMLGregorianCalendar newXMLGregorianCalendar() { return null; } public XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation) { return null; } public XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal) { return null; } public XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year, int month, int day, int hour, int minute, int second, BigDecimal fractionalSecond, int timezone) { return null; } } public static class FakeDuration extends Duration { public int getSign() { return 123456789; } public Number getField(Field field) { return null; } public boolean isSet(Field field) { return false; } public Duration add(Duration rhs) { return null; } public void addTo(Calendar calendar) { } public Duration multiply(BigDecimal factor) { return null; } public Duration negate() { return null; } public Duration normalizeWith(Calendar startTimeInstant) { return null; } public int compare(Duration duration) { return 0; } public int hashCode() { return 0; } } public static class FakeXPathFactory extends XPathFactory { public boolean isObjectModelSupported(String objectModel) { return XPathFactory.DEFAULT_OBJECT_MODEL_URI.equals(objectModel); } public void setFeature(String name, boolean value) throws XPathFactoryConfigurationException { } public boolean getFeature(String name) throws XPathFactoryConfigurationException { return false; } public void setXPathVariableResolver(XPathVariableResolver resolver) { } public void setXPathFunctionResolver(XPathFunctionResolver resolver) { } public XPath newXPath() { return new FakeXPath(); } } public static class FakeXPath implements XPath { public void reset() { } public void setXPathVariableResolver(XPathVariableResolver resolver) { } public XPathVariableResolver getXPathVariableResolver() { return null; } public void setXPathFunctionResolver(XPathFunctionResolver resolver) { } public XPathFunctionResolver getXPathFunctionResolver() { return null; } public void setNamespaceContext(NamespaceContext nsContext) { } public NamespaceContext getNamespaceContext() { return null; } public XPathExpression compile(String expression) throws XPathExpressionException { return null; } public Object evaluate(String expression, Object item, QName returnType) throws XPathExpressionException { return null; } public String evaluate(String expression, Object item) throws XPathExpressionException { return null; } public Object evaluate(String expression, InputSource source, QName returnType) throws XPathExpressionException { return null; } public String evaluate(String expression, InputSource source) throws XPathExpressionException { return null; } } public static class FakeSchemaFactory extends SchemaFactory { public boolean isSchemaLanguageSupported(String schemaLanguage) { return XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(schemaLanguage); } public void setErrorHandler(ErrorHandler errorHandler) { } public ErrorHandler getErrorHandler() { return null; } public void setResourceResolver(LSResourceResolver resourceResolver) { } public LSResourceResolver getResourceResolver() { return null; } public Schema newSchema(Source[] schemas) throws SAXException { return null; } public Schema newSchema() throws SAXException { return new FakeSchema(); } } public static class FakeSchema extends Schema { public Validator newValidator() { return null; } public ValidatorHandler newValidatorHandler() { return null; } } public static class FakeXMLReader implements XMLReader { public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return false; } public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { } public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return "fake-fake-fake"; } public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { } public void setEntityResolver(EntityResolver resolver) { } public EntityResolver getEntityResolver() { return null; } public void setDTDHandler(DTDHandler handler) { } public DTDHandler getDTDHandler() { return null; } public void setContentHandler(ContentHandler handler) { } public ContentHandler getContentHandler() { return null; } public void setErrorHandler(ErrorHandler handler) { } public ErrorHandler getErrorHandler() { return null; } public void parse(InputSource input) throws IOException, SAXException { } public void parse(String systemId) throws IOException, SAXException { } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/JarResourceLoaderTest.java000066400000000000000000000074021257205723500304750ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.PathFilter; import org.junit.Assert; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; /** * Test the functionality of the JarResourceLoader. * * @author John Bailey */ public class JarResourceLoaderTest extends AbstractResourceLoaderTestCase { private JarFile jarFile; protected ResourceLoader createLoader(final PathFilter exportFilter) throws Exception { File fileResourceRoot = getResource("test/fileresourceloader"); // Copy the classfile over copyResource("org/jboss/modules/test/TestClass.class", "test/fileresourceloader", "org/jboss/modules/test"); // Build a jar to match the fileresource loader final File outputFile = new File(getResource("test"), "jarresourceloader/test.jar"); outputFile.getParentFile().mkdirs(); buildJar(fileResourceRoot, outputFile); // Create the jar file and resource loader jarFile = new JarFile(outputFile, true); return new JarFileResourceLoader("test-root", jarFile); } @Override protected void assertResource(Resource resource, String fileName) { final JarEntry entry = jarFile.getJarEntry(fileName); Assert.assertEquals(entry.getSize(), resource.getSize()); } private void buildJar(final File source, final File targetFile) throws IOException { final JarOutputStream target = new JarOutputStream(new FileOutputStream(targetFile)); final String sourceBase = source.getPath(); add(sourceBase, source, target); target.close(); } private void add(final String sourceBase, final File source, final JarOutputStream target) throws IOException { BufferedInputStream in = null; String entryName = source.getPath().replace(sourceBase, "").replace("\\", "/"); if(entryName.startsWith("/")) entryName = entryName.substring(1); try { if (source.isDirectory()) { if (!entryName.isEmpty()) { if (!entryName.endsWith("/")) entryName += "/"; final JarEntry entry = new JarEntry(entryName); target.putNextEntry(entry); target.closeEntry(); } for (File nestedFile : source.listFiles()) add(sourceBase, nestedFile, target); return; } final JarEntry entry = new JarEntry(entryName); target.putNextEntry(entry); in = new BufferedInputStream(new FileInputStream(source)); byte[] buffer = new byte[1024]; int count = 0; while ((count = in.read(buffer)) != -1) { target.write(buffer, 0, count); } target.closeEntry(); } finally { if (in != null) in.close(); } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/LayeredModulePathTest.java000066400000000000000000000601131257205723500304700ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import junit.framework.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * Tests of {@link LocalModuleLoader} when "layers" and "add-ons" are configured. * * @author Brian Stansberry (c) 2012 Red Hat Inc. */ public class LayeredModulePathTest extends AbstractModuleTestCase { private static final String PATH = "test/layeredmodulepath/"; private static final ModuleIdentifier SHARED = ModuleIdentifier.create("test.shared"); private String originalModulePath; private File reposRoot; private File repoA; private File repoB; @Before public void setUp() throws Exception { originalModulePath = System.getProperty("module.path"); reposRoot = new File(getResource(PATH), "repos"); if (!reposRoot.mkdirs() && !reposRoot.isDirectory()) { throw new IllegalStateException("Cannot create reposRoot"); } repoA = new File(reposRoot, "root-a"); if (!repoA.mkdirs() && !repoA.isDirectory()) { throw new IllegalStateException("Cannot create reposA"); } repoB = new File(reposRoot, "root-b"); if (!repoB.mkdirs() && !repoB.isDirectory()) { throw new IllegalStateException("Cannot create reposB"); } } @After public void tearDown() throws Exception { if (reposRoot != null) { cleanFile(reposRoot); } if (originalModulePath != null) { System.setProperty("module.path", originalModulePath); } else { System.clearProperty("module.path"); } } private void cleanFile(File file) { File[] children = file.listFiles(); if (children != null) { for (File child : children) { cleanFile(child); } } if (!file.delete() && file.exists()) { file.deleteOnExit(); } } @Test public void testBaseLayer() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base")); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "base"); validateModuleLoading(standardPath, false, false, false, "base"); } @Test public void testSpecifiedBaseLayer() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", false, false, "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "base"); validateModuleLoading(standardPath, false, false, false, "base"); } @Test public void testSimpleOverlay() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base"), "top"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "top", "base"); validateModuleLoading(standardPath, false, false, false, "top", "base"); } @Test public void testSpecifiedBaseLayerWithSimpleOverlay() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", false, false, "top", "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "top", "base"); validateModuleLoading(standardPath, false, false, false, "top", "base"); } @Test public void testMultipleOverlays() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base"), "top", "mid"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "top", "mid", "base"); validateModuleLoading(standardPath, false, false, false, "top", "mid", "base"); } @Test public void testSpecifiedBaseLayerWithMultipleOverlays() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", false, false, "top", "mid", "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "top", "mid", "base"); validateModuleLoading(standardPath, false, false, false, "top", "mid", "base"); } @Test public void testBasePlusAddOns() throws Exception { createRepo("root-a", true, false, Collections.singletonList("base")); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "base"); validateModuleLoading(standardPath, true, false, false, "base"); } @Test public void testSpecifiedBasePlusAddOns() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", true, false, "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "base"); validateModuleLoading(standardPath, true, false, false, "base"); } @Test public void testLayersAndAddOns() throws Exception { createRepo("root-a", true, false, Collections.singletonList("base"), "top", "mid"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "top", "mid", "base"); validateModuleLoading(standardPath, true, false, false, "top", "mid", "base"); } @Test public void testSpecifiedBaseLayersAndAddOns() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", true, false, "top", "mid", "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "top", "mid", "base"); validateModuleLoading(standardPath, true, false, false, "top", "mid", "base"); } @Test public void testBaseLayerAndUser() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base")); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "base"); validateModuleLoading(standardPath, false, false, false, "base"); } @Test public void testSpecifiedBaseLayerAndUser() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", false, true, "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "base"); validateModuleLoading(standardPath, false, true, true, "base"); } @Test public void testSingleRootComplete() throws Exception { createRepo("root-a", true, false, Collections.singletonList("base"), "top", "mid"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "top", "mid", "base"); validateModuleLoading(standardPath, true, false, false, "top", "mid", "base"); } @Test public void testSpecifiedBaseSingleRootComplete() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", true, true, "top", "mid", "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "top", "mid", "base"); validateModuleLoading(standardPath, true, true, true, "top", "mid", "base"); } @Test public void testSecondRepoHigherPrecedence() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base")); createRepo("root-b", false, true); File[] standardPath = { repoB, repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 1, 0, false, "base"); validateModuleLoading(standardPath, false, true, true, "base"); } @Test public void testSecondRepoLowerPrecedence() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base")); createRepo("root-b", false, true); File[] standardPath = { repoA, repoB }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, 2, false, "base"); validateModuleLoading(standardPath, false, true, false, "base"); } @Test public void testExtraneousOverlay() throws Exception { createRepo("root-a", false, false, Arrays.asList("base", "mid"), "top"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "top", "base"); validateModuleLoading(standardPath, false, false, false, "top", "base"); } @Test public void testSpecifiedBaseLayerWithExtraneousOverlay() throws Exception { // This setup puts "base" in layers.conf createRepo("root-a", false, false, Arrays.asList("mid"), "top", "base"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "top", "base"); validateModuleLoading(standardPath, false, false, false, "top", "base"); } /** Tests that setting up add-ons has no effect without the layers structure */ @Test public void testLayersRequiredForAddOns() throws Exception { createRepo("root-a", true, false); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false); validateModuleLoading(standardPath, false, false, false); // Now add the layers/base dir new File(repoA, "system/layers/base").mkdirs(); modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, true, "base"); validateModuleLoading(standardPath, true, false, false); } @Test public void testRejectConfWithNoStructure() throws Exception { createRepo("root-a", false, false); writeLayersConf("root-a", "top"); File[] standardPath = { repoA }; try { LayeredModulePathFactory.resolveLayeredModulePath(standardPath); Assert.fail("layers.conf with no layers should fail"); } catch (Exception good) { // good } } @Test public void testRejectConfWithMissingLayer() throws Exception { createRepo("root-a", false, false, Arrays.asList("top", "base")); writeLayersConf("root-a", "top", "mid"); File[] standardPath = { repoA }; try { LayeredModulePathFactory.resolveLayeredModulePath(standardPath); Assert.fail("layers.conf with no layers should fail"); } catch (Exception good) { // good } } @Test public void testEmptyLayersConf() throws Exception { createRepo("root-a", false, false, Collections.singletonList("base")); writeLayersConf("root-a"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); validateModulePath(modulePath, repoA, 0, -1, false, "base"); validateModuleLoading(standardPath, false, false, false, "base"); } @Test public void testLayersOverlayModulePath() throws Exception { createRepo("root-a", false, false, Arrays.asList("top", "base")); writeLayersConf("root-a", "top", "base"); createOverlays(repoA, "top", false, "top1", "top2"); createOverlays(repoA, "base", false, "base1", "base2"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); Assert.assertEquals(7, modulePath.length); Assert.assertEquals(repoA, modulePath[0]); Assert.assertEquals(new File(repoA, "system/layers/top/.overlays/top1"), modulePath[1]); Assert.assertEquals(new File(repoA, "system/layers/top/.overlays/top2"), modulePath[2]); Assert.assertEquals(new File(repoA, "system/layers/top"), modulePath[3]); Assert.assertEquals(new File(repoA, "system/layers/base/.overlays/base1"), modulePath[4]); Assert.assertEquals(new File(repoA, "system/layers/base/.overlays/base2"), modulePath[5]); Assert.assertEquals(new File(repoA, "system/layers/base"), modulePath[6]); } @Test public void testAddOnsOverlayModulePath() throws Exception { createRepo("root-a", true, false, Arrays.asList("base")); writeLayersConf("root-a", "base"); createOverlays(repoA, "a", true, "a"); createOverlays(repoA, "b", true, "b"); File[] standardPath = { repoA }; File[] modulePath = LayeredModulePathFactory.resolveLayeredModulePath(standardPath); Assert.assertEquals(6, modulePath.length); Assert.assertEquals(repoA, modulePath[0]); Assert.assertEquals(new File(repoA, "system/layers/base"), modulePath[1]); // The order of the add-ons is non deterministic Assert.assertEquals(".overlays", modulePath[2].getParentFile().getName()); final String firstOverlay = modulePath[2].getName(); Assert.assertEquals(new File(repoA, "system/add-ons/" + firstOverlay), modulePath[3]); Assert.assertEquals(".overlays", modulePath[4].getParentFile().getName()); final String secondOverlays = modulePath[4].getName(); Assert.assertEquals(new File(repoA, "system/add-ons/" + secondOverlays), modulePath[5]); } private void writeLayersConf(String rootName, String... layers) throws IOException { if (layers != null && layers.length > 0) { StringBuilder sb = new StringBuilder("layers="); for (int i = 0; i < layers.length; i++) { if (i > 0) { sb.append(','); } sb.append(layers[i]); } File repo = "root-a".equals(rootName) ? repoA : repoB; File layersConf = new File(repo, "layers.conf"); layersConf.createNewFile(); FileWriter fw = new FileWriter(layersConf); try { PrintWriter pw = new PrintWriter(fw); pw.println(sb.toString()); pw.close(); } finally { try { fw.close(); } catch (Exception e) { // meh } } } } private void createRepo(String rootName, boolean includeAddons, boolean includeUser, String... layers) throws Exception { List empty = Collections.emptyList(); createRepo(rootName, includeAddons, includeUser, empty, layers); } private void createRepo(String rootName, boolean includeAddons, boolean includeUser, List extraLayers, String... layers) throws Exception { if (layers != null && layers.length > 0) { writeLayersConf(rootName, layers); for (String layer : layers) { createLayer(rootName, layer); } } if (extraLayers != null) { for (String extraLayer : extraLayers) { createLayer(rootName, extraLayer); } } if (includeAddons) { createAddOn(rootName, "a"); createAddOn(rootName, "b"); } if (includeUser) { createUserModules(rootName); } } private void createLayer(String rootName, String layerName) throws Exception { createModules("layers/" + layerName, rootName + "/system/layers/" + layerName, layerName); } private void createAddOn(String rootName, String addOnName) throws Exception { createModules("add-ons/" + addOnName, rootName + "/system/add-ons/" + addOnName, addOnName); } private void createUserModules(String rootName) throws Exception { createModules("user", rootName, "user"); } private void createModules(String sourcePath, String relativeRepoPath, String uniqueName) throws Exception { copyResource(PATH + sourcePath + "/shared/module.xml", PATH, "repos/" + relativeRepoPath + "/test/shared/main"); copyResource(PATH + sourcePath + "/unique/module.xml", PATH, "repos/" + relativeRepoPath + "/test/" + uniqueName + "/main"); } private void validateModulePath(File[] modulePath, File repoRoot, int expectedStartPos, int expectedOtherRootPos, boolean expectAddons, String... layers) { int expectedLength = 1 + layers.length + (expectAddons ? 2 : 0); // Validate positional parameters -- check for bad test writers ;) if (expectedOtherRootPos < 0) { Assert.assertEquals(0, expectedStartPos); // } else if (expectedStartPos == 0) { Assert.assertEquals(expectedLength, expectedOtherRootPos); } if (expectedOtherRootPos < 1) { Assert.assertEquals("Correct module path length", expectedStartPos + expectedLength, modulePath.length); } else { Assert.assertTrue("Correct module path length", modulePath.length > expectedStartPos + expectedLength); } Assert.assertEquals(repoRoot, modulePath[expectedStartPos]); for (int i = 0; i < layers.length; i++) { File layer = new File(repoRoot, "system/layers/" + layers[i]); Assert.assertEquals(layer, modulePath[expectedStartPos + i + 1]); } if (expectAddons) { File addOnBase = new File(repoRoot, "system/add-ons"); Set valid = new HashSet(Arrays.asList("a", "b")); for (int i = 0; i < 2; i++) { File addOn = modulePath[expectedStartPos + layers.length + i + 1]; Assert.assertEquals(addOnBase, addOn.getParentFile()); String addOnName = addOn.getName(); Assert.assertTrue(addOnName, valid.remove(addOnName)); } } if (expectedOtherRootPos == 0) { for (int i = 0; i < expectedStartPos; i++) { validateNotChild(modulePath[i], repoRoot); } } else if (expectedOtherRootPos > 0) { for (int i = expectedOtherRootPos; i < modulePath.length; i++) { validateNotChild(modulePath[i], repoRoot); } } } private void validateNotChild(File file, File repoRoot) { File stop = repoRoot.getParentFile(); File testee = file; while (testee != null && !testee.equals(stop)) { Assert.assertFalse(testee.equals(repoRoot)); testee = testee.getParentFile(); } } private void validateModuleLoading(File[] standardPath, boolean expectAddOns, boolean expectUser, boolean expectUserPrecedence, String... layers) throws ModuleLoadException { // This is nasty, but the alternative is exposing the layers config stuff in the LocalModuleLoader API setUpModulePathProperty(standardPath); ModuleLoader moduleLoader = new LocalModuleLoader(); // Validate the expected path produced the shared module if (expectUser || layers.length > 0 || expectAddOns) { Module shared = moduleLoader.loadModule(SHARED); String sharedProp = shared.getProperty("test.prop"); if (expectUserPrecedence) { Assert.assertEquals("user", sharedProp); } else if (layers.length > 0) { Assert.assertEquals(layers[0], sharedProp); } else if (expectAddOns) { Assert.assertTrue("a".equals(sharedProp) || "b".equals(sharedProp)); } } // Validate the expected unique modules are present Set layersSet = new HashSet(Arrays.asList(layers)); loadModule(moduleLoader, "user", expectUser); loadModule(moduleLoader, "top", layersSet.contains("top")); loadModule(moduleLoader, "mid", layersSet.contains("mid")); loadModule(moduleLoader, "base", layersSet.contains("base")); loadModule(moduleLoader, "a", expectAddOns); loadModule(moduleLoader, "b", expectAddOns); } private void setUpModulePathProperty(File[] standardPath) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < standardPath.length; i++) { if (i > 0) { sb.append(File.pathSeparatorChar); } sb.append(standardPath[i].getAbsolutePath()); } System.setProperty("module.path", sb.toString()); } private void loadModule(ModuleLoader moduleLoader, String moduleName, boolean expectAvailable) { ModuleIdentifier id = ModuleIdentifier.create("test." + moduleName); try { Module module = moduleLoader.loadModule(id); if (!expectAvailable) { Assert.fail("test." + moduleName + " should not be loadable"); } String prop = module.getProperty("test.prop"); Assert.assertEquals(moduleName, prop); } catch (ModuleLoadException e) { if (expectAvailable) { Assert.fail(e.getMessage()); } } } private void createOverlays(final File root, final String name, boolean addOn, String... overlays) throws IOException { final File system = new File(root, "system"); final File layers = addOn ? new File(system, "add-ons") : new File(system, "layers"); final File repo = new File(layers, name); final File overlaysRoot = new File(repo, ".overlays"); overlaysRoot.mkdir(); final File overlaysConfig = new File(overlaysRoot, ".overlays"); final OutputStream os = new FileOutputStream(overlaysConfig); try { for (final String overlay : overlays) { os.write(overlay.getBytes()); os.write('\n'); } } finally { if (os != null) try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/LocalModuleLoaderTest.java000066400000000000000000000050421257205723500304470ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.junit.Before; import org.junit.Test; import java.io.File; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; /** * Test to verify the functionality of the LocalModuleLoader. * * @author John Bailey */ public class LocalModuleLoaderTest extends AbstractModuleTestCase { private ModuleLoader moduleLoader; @Before public void setupModuleLoader() throws Exception { final File repoRoot = getResource("test/repo"); moduleLoader = new LocalModuleLoader(new File[] {repoRoot}); } @Test public void testBasicLoad() throws Exception { Module module = moduleLoader.loadModule(MODULE_ID); assertNotNull(module); } @Test public void testCurrent() throws Exception { ModuleLoader loader = Module.getCallerModuleLoader(); System.out.println(loader); } @Test public void testLoadWithDeps() throws Exception { Module module = moduleLoader.loadModule(ModuleIdentifier.fromString("test.with-deps")); assertNotNull(module); } @Test public void testLoadWithBadDeps() throws Exception { try { moduleLoader.loadModule(ModuleIdentifier.fromString("test.bad-deps.1_0")); fail("Should have thrown a ModuleNotFoundException"); } catch(ModuleNotFoundException expected) {} } @Test public void testLoadWithCircularDeps() throws Exception { assertNotNull(moduleLoader.loadModule(ModuleIdentifier.fromString("test.circular-deps-A"))); assertNotNull(moduleLoader.loadModule(ModuleIdentifier.fromString("test.circular-deps-B"))); assertNotNull(moduleLoader.loadModule(ModuleIdentifier.fromString("test.circular-deps-C"))); assertNotNull(moduleLoader.loadModule(ModuleIdentifier.fromString("test.circular-deps-D"))); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/MavenResourceTest.java000077500000000000000000000060631257205723500277050ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.net.URL; import org.jboss.modules.util.Util; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; /** * @author Bill Burke * @version $Revision: 1 $ */ public class MavenResourceTest { protected static final ModuleIdentifier MODULE_ID = ModuleIdentifier.fromString("test.maven"); protected static final ModuleIdentifier MODULE_ID2 = ModuleIdentifier.fromString("test.maven:non-main"); @Rule public TemporaryFolder tmpdir = new TemporaryFolder(); private ModuleLoader moduleLoader; @Before public void setupRepo() throws Exception { final File repoRoot = Util.getResourceFile(getClass(), "test/repo"); moduleLoader = new LocalModuleLoader(new File[]{repoRoot}); } @Test public void testWithPassedRepository() throws Exception { System.setProperty("maven.repo.local", tmpdir.newFolder("repository").getAbsolutePath()); System.setProperty("remote.maven.repo", "http://repository.jboss.org/nexus/content/groups/public/"); try { Module module = moduleLoader.loadModule(MODULE_ID); URL url = module.getResource("org/jboss/resteasy/plugins/providers/jackson/ResteasyJacksonProvider.class"); System.out.println(url); Assert.assertNotNull(url); } finally { System.clearProperty("maven.repo.local"); System.clearProperty("remote.repository"); } } @Test public void testDefaultRepositories() throws Exception { Module module = moduleLoader.loadModule(MODULE_ID2); URL url = module.getResource("org/jboss/resteasy/plugins/providers/jackson/ResteasyJacksonProvider.class"); System.out.println(url); Assert.assertNotNull(url); } /** * we test if it uses repostiory user has configured in user.home/.m2/settings.xml or M2_HOME/conf/settings.xml * * @throws Exception */ @Test @Ignore("Test artifact must exists in local repo but nowhere else, mostly meant for manual testing") public void testCustomRepository() throws Exception { MavenArtifactUtil.resolveJarArtifact("org.wildfly:wildfly-clustering-infinispan:9.0.0.Alpha1-SNAPSHOT"); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ModuleClassLoaderTest.java000066400000000000000000000415361257205723500304720ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.MultiplePathFilterBuilder; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.test.ImportedClass; import org.jboss.modules.test.ImportedInterface; import org.jboss.modules.test.TestClass; import org.jboss.modules.util.TestModuleLoader; import org.jboss.modules.util.TestResourceLoader; import org.junit.Before; import org.junit.Test; import java.net.URL; import java.util.Enumeration; import java.util.List; import static org.jboss.modules.util.Util.toList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Test to verify module functionality. * * @author John Bailey * @author Flavia Rainone */ public class ModuleClassLoaderTest extends AbstractModuleTestCase { private static final ModuleIdentifier MODULE_WITH_CONTENT_ID = ModuleIdentifier.fromString("test-with-content"); private static final ModuleIdentifier MODULE_WITH_RESOURCE_ID = ModuleIdentifier.fromString("test-with-resource"); private static final ModuleIdentifier MODULE_TO_IMPORT_ID = ModuleIdentifier.fromString("test-to-import"); private static final ModuleIdentifier MODULE_WITH_EXPORT_ID = ModuleIdentifier.fromString("test-with-export"); private static final ModuleIdentifier MODULE_WITH_DOUBLE_EXPORT_ID = ModuleIdentifier.fromString("test-with-double-export"); private static final ModuleIdentifier MODULE_WITH_INVERTED_DOUBLE_EXPORT_ID = ModuleIdentifier.fromString("test-with-inverted-double-export"); private static final ModuleIdentifier MODULE_WITH_FILTERED_EXPORT_ID = ModuleIdentifier.fromString("test-with-filtered-export"); private static final ModuleIdentifier MODULE_WITH_FILTERED_IMPORT_ID = ModuleIdentifier.fromString("test-with-filtered-import"); private static final ModuleIdentifier MODULE_WITH_FILTERED_DOUBLE_EXPORT_ID = ModuleIdentifier.fromString("test-with-filtered-double-export"); private TestModuleLoader moduleLoader; @Before public void setupModuleLoader() throws Exception { moduleLoader = new TestModuleLoader(); final ModuleSpec.Builder moduleWithContentBuilder = ModuleSpec.build(MODULE_WITH_CONTENT_ID); moduleWithContentBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(TestClass.class) .addResources(getResource("test/modulecontentloader/rootOne")) .create() )); moduleWithContentBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_TO_IMPORT_ID)); moduleWithContentBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithContentBuilder.create()); final ModuleSpec.Builder moduleWithResourceBuilder = ModuleSpec.build(MODULE_WITH_RESOURCE_ID); moduleWithResourceBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(TestClass.class) .addResources(getResource("class-resources")) .create() )); moduleWithResourceBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_TO_IMPORT_ID)); moduleWithResourceBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithResourceBuilder.create()); final ModuleSpec.Builder moduleToImportBuilder = ModuleSpec.build(MODULE_TO_IMPORT_ID); moduleToImportBuilder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec( TestResourceLoader.build() .addClass(ImportedClass.class) .addClass(ImportedInterface.class) .addResources(getResource("test/modulecontentloader/rootTwo")) .create() )); moduleToImportBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleToImportBuilder.create()); final ModuleSpec.Builder moduleWithExportBuilder = ModuleSpec.build(MODULE_WITH_EXPORT_ID); moduleWithExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_TO_IMPORT_ID, true, false)); moduleWithExportBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithExportBuilder.create()); final MultiplePathFilterBuilder nestedAndOrgJBossExcludingBuilder = PathFilters.multiplePathFilterBuilder(true); nestedAndOrgJBossExcludingBuilder.addFilter(PathFilters.match("org/jboss/**"), false); nestedAndOrgJBossExcludingBuilder.addFilter(PathFilters.match("nested"), false); final ModuleSpec.Builder moduleWithExportFilterBuilder = ModuleSpec.build(MODULE_WITH_FILTERED_EXPORT_ID); moduleWithExportFilterBuilder.addDependency(DependencySpec.createModuleDependencySpec(nestedAndOrgJBossExcludingBuilder.create(), null, MODULE_TO_IMPORT_ID, false)); moduleWithExportFilterBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithExportFilterBuilder.create()); final ModuleSpec.Builder moduleWithImportFilterBuilder = ModuleSpec.build(MODULE_WITH_FILTERED_IMPORT_ID); moduleWithImportFilterBuilder.addDependency(DependencySpec.createModuleDependencySpec(nestedAndOrgJBossExcludingBuilder.create(), PathFilters.rejectAll(), null, MODULE_TO_IMPORT_ID, false)); moduleWithImportFilterBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithImportFilterBuilder.create()); final ModuleSpec.Builder moduleWithDoubleExportBuilder = ModuleSpec.build(MODULE_WITH_DOUBLE_EXPORT_ID); moduleWithDoubleExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_TO_IMPORT_ID, true)); moduleWithDoubleExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_WITH_CONTENT_ID, true)); moduleWithDoubleExportBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithDoubleExportBuilder.create()); final ModuleSpec.Builder moduleWithInvertedDoubleExportBuilder = ModuleSpec.build(MODULE_WITH_INVERTED_DOUBLE_EXPORT_ID); moduleWithInvertedDoubleExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_WITH_CONTENT_ID, true)); moduleWithInvertedDoubleExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_TO_IMPORT_ID, true)); moduleWithInvertedDoubleExportBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithInvertedDoubleExportBuilder.create()); final ModuleSpec.Builder moduleWithFilteredDoubleExportBuilder = ModuleSpec.build(MODULE_WITH_FILTERED_DOUBLE_EXPORT_ID); moduleWithFilteredDoubleExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(PathFilters.not(PathFilters.match("nested")), PathFilters.acceptAll(), null, MODULE_TO_IMPORT_ID, false)); moduleWithFilteredDoubleExportBuilder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_WITH_EXPORT_ID, true)); moduleWithFilteredDoubleExportBuilder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(moduleWithFilteredDoubleExportBuilder.create()); } @Test public void testLocalClassLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); try { Class testClass = classLoader.loadClass("org.jboss.modules.test.TestClass"); assertNotNull(testClass); } catch (ClassNotFoundException e) { fail("Should have loaded local class"); } } @Test public void testResourceLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_RESOURCE_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); try { Class testClass = classLoader.loadClass("org.jboss.modules.test.TestClass"); // direct assertNotNull(testClass.getResource("/file1.txt")); // translates to /file1.txt assertNotNull(testClass.getResource("file2.txt")); // translates to /org/jboss/modules/test/file2.txt // relative assertNotNull(testClass.getResource("../../../../file1.txt")); // should translate to /file1.txt assertNotNull(testClass.getResource("test/../file2.txt")); // should translate to /org/jboss/modules/test/file2.txt } catch (ClassNotFoundException e) { e.printStackTrace(); fail("Should have loaded local class"); } } @Test public void testLocalClassLoadNotFound() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); try { classLoader.loadClass("org.jboss.modules.test.BogusClass"); fail("Should have thrown ClassNotFoundException"); } catch (ClassNotFoundException expected) { } } @Test public void testImportClassLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); try { Class testClass = classLoader.loadClass("org.jboss.modules.test.ImportedClass"); assertNotNull(testClass); } catch (ClassNotFoundException e) { fail("Should have loaded imported class"); } } @Test public void testFilteredImportClassLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_FILTERED_IMPORT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); try { classLoader.loadClass("org.jboss.modules.test.ImportedClass"); fail("Should have thrown ClassNotFoundException"); } catch (ClassNotFoundException expected) { } } @Test public void testDoubleExportCLassLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_DOUBLE_EXPORT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); Class testClass = classLoader.loadExportedClass("org.jboss.modules.test.ImportedClass"); assertNotNull(testClass); testClass = classLoader.loadExportedClass("org.jboss.modules.test.TestClass"); assertNotNull(testClass); } @Test public void testInvertedDoubleExportCLassLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_INVERTED_DOUBLE_EXPORT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); Class testClass = classLoader.loadExportedClass("org.jboss.modules.test.ImportedClass"); assertNotNull(testClass); testClass = classLoader.loadExportedClass("org.jboss.modules.test.TestClass"); assertNotNull(testClass); } @Test public void testFilteredDoubleExportCLassLoad() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_FILTERED_DOUBLE_EXPORT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); Class testClass = classLoader.loadExportedClass("org.jboss.modules.test.ImportedClass"); assertNotNull(testClass); } @Test public void testLocalResourceRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final URL resUrl = classLoader.getResource("test.txt"); assertNotNull(resUrl); } @Test public void testLocalResourceRetrievalNotFound() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final URL resUrl = classLoader.getResource("bogus.txt"); assertNull(resUrl); } @Test public void testImportResourceRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final URL resUrl = classLoader.getResource("testTwo.txt"); assertNotNull(resUrl); } @Test public void testFilteredImportResourceRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_FILTERED_IMPORT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); URL resUrl = classLoader.getResource("nested/nested.txt"); assertNull(resUrl); } @Test public void testLocalResourcesRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final Enumeration resUrls = classLoader.getResources("test.txt"); assertNotNull(resUrls); final List resUrlList = toList(resUrls); assertEquals(1, resUrlList.size()); assertTrue(resUrlList.get(0).getPath().contains("rootOne")); } @Test public void testLocalResourcesRetrievalNotFound() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final Enumeration resUrls = classLoader.getResources("bogus.txt"); assertNotNull(resUrls); final List resUrlList = toList(resUrls); assertTrue(resUrlList.isEmpty()); } @Test public void testImportResourcesRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final Enumeration resUrls = classLoader.getResources("testTwo.txt"); assertNotNull(resUrls); final List resUrlList = toList(resUrls); assertEquals(1, resUrlList.size()); assertTrue(resUrlList.get(0).getPath().contains("rootTwo")); } @Test public void testLocalAndImportResourcesRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final Enumeration resUrls = classLoader.getResources("nested/nested.txt"); assertNotNull(resUrls); final List resUrlList = toList(resUrls); assertEquals(2, resUrlList.size()); boolean rootOne = false; boolean rootTwo = false; for(URL resUrl : resUrlList) { if(!rootOne) rootOne = resUrl.getPath().contains("rootOne"); if(!rootTwo) rootTwo = resUrl.getPath().contains("rootTwo"); } assertTrue(rootOne); assertTrue(rootTwo); } @Test public void testFilteredImportResourcesRetrieval() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_FILTERED_IMPORT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); Enumeration resUrls = classLoader.getResources("nested/nested.txt"); List resUrlList = toList(resUrls); assertTrue(resUrlList.isEmpty()); } @Test public void testManifest() throws Exception { final Module testModule = moduleLoader.loadModule(MODULE_WITH_CONTENT_ID); final ModuleClassLoader classLoader = testModule.getClassLoader(); final Class testClass = classLoader.loadClass("org.jboss.modules.test.TestClass"); System.out.println(testClass.getClassLoader()); final Package pkg = testClass.getPackage(); assertEquals("JBoss Modules Test Classes", pkg.getSpecificationTitle()); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ModuleExportTest.java000066400000000000000000000153441257205723500275550ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.lang.reflect.Field; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.test.ImportedClass; import org.jboss.modules.util.TestModuleLoader; import org.jboss.modules.util.TestResourceLoader; import org.junit.Test; /** * Test to verify the module export dependencies and imports are created correctly. Each module should have an entry * directly to the module that has an exported path. * * @author John E. Bailey */ public class ModuleExportTest extends AbstractModuleTestCase { private static final ModuleIdentifier MODULE_A = ModuleIdentifier.fromString("a"); private static final ModuleIdentifier MODULE_B = ModuleIdentifier.fromString("b"); private static final ModuleIdentifier MODULE_C = ModuleIdentifier.fromString("c"); private static final ModuleIdentifier MODULE_D = ModuleIdentifier.fromString("d"); @Test public void testExportDependencies() throws Exception { final TestModuleLoader moduleLoader = new TestModuleLoader(); ModuleSpec.Builder builder = ModuleSpec.build(MODULE_A); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_B, true, false)); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_B); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_C, true, false)); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_D)); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_C); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_D); moduleLoader.addModuleSpec(builder.create()); Module module = moduleLoader.loadModule(MODULE_A); final Set dependencyExports = new HashSet(); getExportedModuleDeps(module, dependencyExports); assertEquals(2, dependencyExports.size()); assertTrue(dependencyExports.contains(MODULE_B)); assertTrue(dependencyExports.contains(MODULE_C)); dependencyExports.clear(); module = moduleLoader.loadModule(MODULE_B); getExportedModuleDeps(module, dependencyExports); assertEquals(1, dependencyExports.size()); assertTrue(dependencyExports.contains(MODULE_C)); dependencyExports.clear(); module = moduleLoader.loadModule(MODULE_C); getExportedModuleDeps(module, dependencyExports); assertEquals(0, dependencyExports.size()); dependencyExports.clear(); module = moduleLoader.loadModule(MODULE_D); getExportedModuleDeps(module, dependencyExports); assertEquals(0, dependencyExports.size()); } private static void getExportedModuleDeps(final Module module, final Set dependencyExports) throws ModuleLoadException { getExportedModuleDeps(module, new HashSet(Collections.singleton(module)), dependencyExports); } private static void getExportedModuleDeps(final Module module, final Set visited, final Set dependencyExports) throws ModuleLoadException { for (Dependency dependency : module.getDependenciesInternal()) { if (dependency instanceof ModuleDependency && dependency.getExportFilter() != PathFilters.rejectAll()) { final ModuleDependency moduleDependency = (ModuleDependency) dependency; final Module md = moduleDependency.getModuleLoader().loadModule(moduleDependency.getIdentifier()); if (md != null && moduleDependency.getExportFilter() != PathFilters.rejectAll()) { if (visited.add(md)) { dependencyExports.add(md.getIdentifier()); getExportedModuleDeps(md, visited, dependencyExports); } } } } } @SuppressWarnings({ "unchecked" }) @Test public void testImportPaths() throws Exception { final TestModuleLoader moduleLoader = new TestModuleLoader(); ModuleSpec.Builder builder = ModuleSpec.build(MODULE_A); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_B, true)); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_B); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_C, true)); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_D)); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_C); builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(TestResourceLoader.build() .addClass(ImportedClass.class) .create() )); builder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_D); moduleLoader.addModuleSpec(builder.create()); Module module = moduleLoader.loadModule(MODULE_A); module.getClassLoader().loadClass(ImportedClass.class.getName()); final Field pathsField = Module.class.getDeclaredField("linkage"); pathsField.setAccessible(true); final Object paths = pathsField.get(module); final Field allPathsField = paths.getClass().getDeclaredField("allPaths"); allPathsField.setAccessible(true); final Map> allPaths = (Map>) allPathsField.get(paths); Module moduleC = moduleLoader.loadModule(MODULE_C); assertEquals(4, allPaths.size()); for(Map.Entry> entry : allPaths.entrySet()) { assertEquals(1, entry.getValue().size()); assertEquals(moduleC.getClassLoaderPrivate().getLocalLoader(), entry.getValue().get(0)); } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ModuleIdentifierTest.java000066400000000000000000000045251257205723500303550ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.junit.Test; /** * @author John E. Bailey */ public class ModuleIdentifierTest { @Test public void testFromString() throws Exception { ModuleIdentifier identifier = ModuleIdentifier.fromString("test.module"); assertEquals("test.module", identifier.getName()); assertEquals("main", identifier.getSlot()); identifier = ModuleIdentifier.fromString("test.module:old"); assertEquals("test.module", identifier.getName()); assertEquals("old", identifier.getSlot()); } @Test public void testToString() { ModuleIdentifier identifier = ModuleIdentifier.fromString("test.module"); assertEquals("test.module:main", identifier.toString()); identifier = ModuleIdentifier.fromString("test.module:old"); assertEquals("test.module:old", identifier.toString()); } @Test public void testInvalidCharacters() throws Exception { try { ModuleIdentifier.fromString("test.module\\test"); } catch (IllegalArgumentException unexpected) { fail("Should not have thrown IllegalArgumentException"); } try { ModuleIdentifier.fromString("test/module/test"); } catch (IllegalArgumentException unexpected) { fail("Should have thrown IllegalArgumentException"); } try { ModuleIdentifier.fromString("test,module,test"); } catch (IllegalArgumentException unexpected) { fail("Should have thrown IllegalArgumentException"); } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ModuleIteratorTest.java000066400000000000000000000121601257205723500300560ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.jar.JarFile; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.jboss.modules.util.TestModuleLoader; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Assert; import org.junit.Test; /** * * * @author Thomas.Diesler@jboss.com */ public class ModuleIteratorTest extends AbstractModuleTestCase { private static final ModuleIdentifier MODULE_A = ModuleIdentifier.fromString("a"); private static final ModuleIdentifier MODULE_B = ModuleIdentifier.fromString("b"); @Test public void testMetaInfServicesIterator() throws Exception { TestModuleLoader moduleLoader = new TestModuleLoader(); ModuleSpec.Builder builder = ModuleSpec.build(MODULE_A); builder.addDependency(DependencySpec.createModuleDependencySpec(MODULE_B, false, false)); PathFilter importFilter = PathFilters.getMetaInfServicesFilter(); PathFilter exportFilter = PathFilters.acceptAll(); builder.addDependency(DependencySpec.createModuleDependencySpec(importFilter, exportFilter, moduleLoader, MODULE_B, false)); moduleLoader.addModuleSpec(builder.create()); builder = ModuleSpec.build(MODULE_B); ResourceLoader resB = new JarFileResourceLoader("jarB", toJarFile(getModuleB())); builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resB)); builder.addDependency(DependencySpec.createLocalDependencySpec()); moduleLoader.addModuleSpec(builder.create()); Module moduleA = moduleLoader.loadModule(MODULE_A); Iterator itres = moduleA.iterateResources(PathFilters.getMetaInfServicesFilter()); Assert.assertTrue("Found a resource", itres.hasNext()); Assert.assertEquals("META-INF/services/org/apache/camel/component/jms", itres.next().getName()); Assert.assertFalse("No other resource", itres.hasNext()); } @Test public void testIterateModules() throws Exception { IterableModuleFinder fakeFinder = new IterableModuleFinder() { private ModuleIdentifier[] modules = { ModuleIdentifier.create("a"), ModuleIdentifier.create("b")}; @Override public Iterator iterateModules(ModuleIdentifier baseIdentifier, boolean recursive) { return new Iterator() { private int pos = 0; @Override public boolean hasNext() { return pos < modules.length; } @Override public ModuleIdentifier next() { return modules[pos++]; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public ModuleSpec findModule(ModuleIdentifier identifier, ModuleLoader delegateLoader) throws ModuleLoadException { for (ModuleIdentifier m : modules) { if (m.equals(identifier)) { return ModuleSpec.build(m).create(); } } return null; } }; ModuleLoader loader = new ModuleLoader(new ModuleFinder[]{fakeFinder}); Iterator it = loader.iterateModules(null, true); int count = 0; while (it.hasNext()) { it.next(); count++; } Assert.assertEquals(2, count); } private JarFile toJarFile(JavaArchive archive) throws IOException { ZipExporter exporter = archive.as(ZipExporter.class); File targetFile = new File("target/shrinkwrap/" + archive.getName()); targetFile.getParentFile().mkdirs(); exporter.exportTo(targetFile, true); return new JarFile(targetFile); } private JavaArchive getModuleB() { JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "moduleB"); archive.addAsManifestResource(new StringAsset("someContent"), "services/org/apache/camel/component/jms"); return archive; } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ModulePropertyTest.java000066400000000000000000000033041257205723500301110ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.io.File; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; /** * Test to verify the functionality of module properties. * * @author David M. Lloyd */ public class ModulePropertyTest extends AbstractModuleTestCase { private ModuleLoader moduleLoader; @Before public void setupModuleLoader() throws Exception { final File repoRoot = getResource("test/repo"); moduleLoader = new LocalModuleLoader(new File[] {repoRoot}); } @Test public void testBasic() throws Exception { Module module = moduleLoader.loadModule(MODULE_ID); assertNull(module.getProperty("non-existent")); assertEquals("blah", module.getProperty("non-existent", "blah")); assertEquals("true", module.getProperty("test.prop.1")); assertEquals("propertyValue", module.getProperty("test.prop.2")); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/PathFilterTest.java000066400000000000000000000051521257205723500271640ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import org.jboss.modules.filter.MultiplePathFilterBuilder; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Test to verify the PathFilter functionality. * * @author John E. Bailey */ public class PathFilterTest { @Test public void testMatch() throws Exception { PathFilter pathFilter = PathFilters.match("foo/**"); assertFalse(pathFilter.accept("foo")); assertTrue(pathFilter.accept("foo/bar")); assertTrue(pathFilter.accept("foo/bar/baz")); pathFilter = PathFilters.match("foo/*"); assertFalse(pathFilter.accept("foo")); assertTrue(pathFilter.accept("foo/bar")); assertTrue(pathFilter.accept("foo/bar/baz")); pathFilter = PathFilters.match("foo"); assertTrue(pathFilter.accept("foo")); assertTrue(pathFilter.accept("foo/bar")); assertTrue(pathFilter.accept("foo/bar/baz")); pathFilter = PathFilters.match("**/bar/**"); assertFalse(pathFilter.accept("foo")); assertFalse(pathFilter.accept("foo/bar")); assertTrue(pathFilter.accept("foo/bar/baz")); assertTrue(pathFilter.accept("foo/baz/bar/biff")); } @Test public void testDelegating() throws Exception { final MultiplePathFilterBuilder builder = PathFilters.multiplePathFilterBuilder(true); builder.addFilter(PathFilters.match("foo/*"), false); builder.addFilter(PathFilters.match("**/bar/**"), false); builder.addFilter(PathFilters.match("baz/**"), false); PathFilter pathFilter = builder.create(); assertTrue(pathFilter.accept("foo")); assertFalse(pathFilter.accept("foo/bar")); assertFalse(pathFilter.accept("foo/bar/baz")); assertFalse(pathFilter.accept("baz/foo/bar")); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/SystemResourcesTest.java000066400000000000000000000040711257205723500303000ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules; import java.net.URL; import java.util.Enumeration; import org.jboss.modules.util.TestModuleLoader; import org.junit.Assert; import org.junit.Test; /** * Test System pkgs resources * * @author Jason T. Greene */ public class SystemResourcesTest { private static final ModuleIdentifier MODULE_A = ModuleIdentifier.fromString("A"); static { System.setProperty("jboss.modules.system.pkgs", "javax.activation"); } @Test public void testResources() throws Exception { final TestModuleLoader moduleLoader = new TestModuleLoader(); ModuleSpec.Builder builder = ModuleSpec.build(MODULE_A); //builder.addDependency(DependencySpec.createModuleDependencySpec(PathFilters.match("org/jboss/modules/**"), PathFilters.rejectAll(), null, ModuleIdentifier.SYSTEM, false)); moduleLoader.addModuleSpec(builder.create()); Module module = moduleLoader.loadModule(MODULE_A); ClassLoader cl = module.getClassLoader(); Enumeration resources = cl.getResources("javax/activation/DataHandler.class"); Assert.assertTrue(resources.hasMoreElements()); resources = cl.getResources("javax/sql/RowSet.class"); Assert.assertFalse(resources.hasMoreElements()); resources = cl.getResources("org/jboss/"); Assert.assertFalse(resources.hasMoreElements()); } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/000077500000000000000000000000001257205723500241705ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/AbstractReapableReferenceTest.java000066400000000000000000000023671257205723500327210ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import org.jboss.modules.ref.util.Assert; /** * Super class for all test cases that apply to reapable references. * * @author Flavia Rainone * @see Reapable */ public abstract class AbstractReapableReferenceTest extends AbstractReferenceTest { final void assertReference(Reference reference, T referenceValue, A attachment, Reaper reaper) { Assert.assertReference(reference, referenceValue, attachment, getTestedReferenceType(), reaper); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/AbstractReferenceTest.java000066400000000000000000000065121257205723500312610ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.jboss.modules.ref.Reference.Type; import org.jboss.modules.ref.util.Assert; import org.junit.Test; /** * Super class for all reference test cases, contains a few tests for functionality common to all * references, and a reference assertion method. * * @author Flavia Rainone */ public abstract class AbstractReferenceTest { abstract Reference createReference(T value, A attachment); abstract Type getTestedReferenceType(); @Test public void referenceEqualsReference() { final Reference reference1 = createReference(new StringBuffer().append("some text text"), (Number) Long.valueOf(5l)); final Reference reference2 = createReference(new StringBuffer().append("some text"), (Number) Double.valueOf(5.5)); final Reference reference3 = createReference(null, null); final Reference reference4 = createReference(new StringBuffer().append("some text text"), (Number) Long.valueOf(5l)); assertEquals(reference1, reference1); assertEquals(reference1.hashCode(), reference1.hashCode()); assertFalse(reference1.equals(reference2)); assertFalse(reference1.equals(reference3)); assertFalse(reference1.equals(reference4)); assertEquals(reference2, reference2); assertEquals(reference2.hashCode(), reference2.hashCode()); assertFalse(reference2.equals(reference3)); assertFalse(reference2.equals(reference4)); assertEquals(reference3, reference3); assertEquals(reference3.hashCode(), reference3.hashCode()); assertFalse(reference3.equals(reference4)); assertEquals(reference4, reference4); assertEquals(reference4.hashCode(), reference4.hashCode()); } @Test public void clearReference() { final Reference reference = createReference(Boolean.TRUE, "attachment for true"); assertTrue(reference.get().booleanValue()); assertEquals("attachment for true", reference.getAttachment()); reference.clear(); assertNull(reference.get()); assertEquals("attachment for true", reference.getAttachment()); } final void assertReference(Reference reference, T referent, A attachment) { Assert.assertReference(reference, referent, attachment, getTestedReferenceType()); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/PhantomReferenceTestCase.java000066400000000000000000000070111257205723500317130ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import java.lang.ref.ReferenceQueue; import java.util.ArrayList; import java.util.Collection; import org.jboss.modules.ref.Reference.Type; import org.jboss.modules.ref.util.TestReaper; import org.junit.Test; /** * Test for PhantomReference. * * @author Flavia Rainone * @see PhantomReference */ public class PhantomReferenceTestCase extends AbstractReapableReferenceTest { @Test public void plainPhantomReference() { final Reference reference = new PhantomReference("referent", "attachment", (ReferenceQueue) null); assertReference(reference, null, "attachment", null); } @Test public void nullPhantomReference() throws Exception { final Reference reference = new PhantomReference(null, Integer.valueOf(0), new ReferenceQueue()); assertReference(reference, null, Integer.valueOf(0), null); } @Test public void phantomReferenceWithReferenceQueue() throws Exception { final ReferenceQueue> referenceQueue = new ReferenceQueue>(); Collection collection = new ArrayList(); final Reference, String> reference = new PhantomReference, String>(collection, "collection", referenceQueue); assertReference(reference, null, "collection", null); collection = null; System.gc(); assertSame(reference, referenceQueue.remove(300)); } @Test public void phantomReferenceWithReaper() throws Exception { Thing thing = new Thing(); final TestReaper reaper = new TestReaper(); final Reference reference = new PhantomReference(thing, null, reaper); assertReference(reference, null, null, reaper); thing = null; System.gc(); assertSame(reference, reaper.getReapedReference()); } @Override @Test public void clearReference() { final Reference reference = createReference(Boolean.TRUE, "attachment for true"); assertNull(reference.get()); assertEquals("attachment for true", reference.getAttachment()); reference.clear(); assertNull(reference.get()); assertEquals("attachment for true", reference.getAttachment()); } @Override Reference createReference(T value, A attachment) { return new PhantomReference(value, attachment, new TestReaper()); } @Override Type getTestedReferenceType() { return Type.PHANTOM; } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/ReferencesTestCase.java000066400000000000000000000207561257205723500305620ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import static org.jboss.modules.ref.util.Assert.assertReference; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.lang.ref.ReferenceQueue; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.TimeUnit; import org.jboss.modules.ref.Reference.Type; import org.jboss.modules.ref.References.ReaperThread; import org.jboss.modules.ref.util.TestReaper; import org.junit.Test; /** * Test for {@link References} class and internal classes. * * @author Flavia Rainone */ public class ReferencesTestCase { @Test public void nullReference() { final Reference nullReference = References.getNullReference(); assertReference(nullReference, null, null, Type.NULL); nullReference.clear(); assertReference(nullReference, null, null, Type.NULL); assertEquals(nullReference, References.create(Type.NULL, null, null)); assertEquals(nullReference, References.create(Type.NULL, null, null, (Reaper) null)); assertEquals(nullReference, References.create(Type.NULL, null, null, (ReferenceQueue) null)); } @Test public void createStrongReference() { final Reference reference = createReference(Type.STRONG); assertTrue(reference instanceof StrongReference); } @Test public void createSoftReference() { final Reference reference = createReference(Type.SOFT); assertTrue(reference instanceof SoftReference); } @Test public void createWeakReference() { final Reference reference = createReference(Type.WEAK); assertTrue(reference instanceof WeakReference); } @Test public void createIllegalPhantomReference() { try { References.create(Type.PHANTOM, "value", "attachment"); fail("IllegalArgumentException expected because of missing reaper/reference queue"); } catch (IllegalArgumentException e) {} } @Test public void createStrongReferenceWithReaper() throws Exception { final Object referent = new Object(); final Reference reference = References.create(Type.STRONG, referent, "attachment", new TestReaper()); assertReference(reference, referent, "attachment", Type.STRONG); assertTrue(reference instanceof StrongReference); } @Test public void createSoftReferenceWithReaper() throws Exception { final Reference reference = createReferenceWithReaper(Type.SOFT, false, false); assertTrue(reference instanceof SoftReference); } @Test public void createWeakReferenceWithReaper() throws Exception { final Reference reference = createReferenceWithReaper(Type.WEAK, false, true); assertTrue(reference instanceof WeakReference); } @Test public void createPhantomReferenceWithReaper() throws Exception { final Reference reference = createReferenceWithReaper(Type.PHANTOM, true, true); assertTrue(reference instanceof PhantomReference); } @Test public void createStrongReferenceWithQueue() throws Exception { final Object referent = new Object(); final Reference reference = References.create(Type.STRONG, referent, "attachment", new ReferenceQueue()); assertReference(reference, referent, "attachment", Type.STRONG); assertTrue(reference instanceof StrongReference); } @Test public void createSoftReferenceWithQueue() throws Exception { final Reference reference = createReferenceWithQueue(Type.SOFT, false, false); assertTrue(reference instanceof SoftReference); } @Test public void createWeakReferenceWithQueue() throws Exception { final Reference reference = createReferenceWithQueue(Type.WEAK, false, true); assertTrue(reference instanceof WeakReference); } @Test public void createPhantomReferenceWithQueue() throws Exception { final Reference reference = createReferenceWithQueue(Type.PHANTOM, true, true); assertTrue(reference instanceof PhantomReference); } @Test public void reapUnreapableReference() throws Exception { Object referent = new Object(); final TestReaper reaper = new TestReaper(); final Reference reference = new UnreapableWeakReference(referent); assertReference(reference, referent, null, Type.WEAK); referent = null; System.gc(); assertNull(reaper.get(200, TimeUnit.MILLISECONDS)); } @Test public void failToReapReference() throws Exception { final TestReaper reaper = new FailToReap(); Object referent = new Object(); final Reference reference = new WeakReference(referent, null, reaper); assertReference(reference, referent, null, Type.WEAK, reaper); referent = null; System.gc(); assertNull(reaper.get(200, TimeUnit.MILLISECONDS)); } private Reference createReference(Type type) { final Reference reference = References.create(type, "value", "attachment"); assertReference(reference, "value", "attachment", type); return reference; } private Reference createReferenceWithReaper(Type type, boolean expectedNullValue, boolean testReaper) throws Exception { Object referent = new Object(); final TestReaper reaper = new TestReaper(); final Reference reference = References.create(type, referent, "attachment", reaper); assertReference(reference, expectedNullValue? null: referent, "attachment", type, reaper); if (testReaper) { referent = null; System.gc(); assertSame(reference, reaper.get()); } return reference; } private Reference, Object> createReferenceWithQueue(Type type, boolean expectedNullValue, boolean testQueue) throws Exception { final Object referenceAttachment = new Object(); Collection referent = new ArrayList(); referent.add(Integer.valueOf(1)); referent.add(Integer.valueOf(11)); referent.add(Integer.valueOf(111)); final ReferenceQueue> referenceQueue = new ReferenceQueue>(); final Reference, Object> reference = References.create(type, referent, referenceAttachment, referenceQueue); assertReference(reference, expectedNullValue? null: referent, referenceAttachment, type, null); if (testQueue) { referent = null; System.gc(); assertSame(reference, referenceQueue.remove(300)); } return reference; } private static final class UnreapableWeakReference extends java.lang.ref.WeakReference implements Reference { public UnreapableWeakReference(Object referent) { super(referent, ReaperThread.REAPER_QUEUE); } @Override public Void getAttachment() { return null; } @Override public Reference.Type getType() { return Type.WEAK; } } private static final class FailToReap extends TestReaper { @Override public void reap(Reference reference) { throw new RuntimeException("fail to reap"); } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/SoftReferenceTestCase.java000066400000000000000000000055671257205723500312360ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import java.lang.ref.ReferenceQueue; import java.util.ArrayList; import java.util.Collection; import org.jboss.modules.ref.Reference.Type; import org.jboss.modules.ref.util.TestReaper; import org.junit.Test; /** * Test for {@link SoftReference}. * * @author Flavia Rainone */ public class SoftReferenceTestCase extends AbstractReapableReferenceTest { @Test public void plainSoftReference() { final Reference reference = new SoftReference("referent", "attachment"); assertReference(reference, "referent", "attachment", null); } @Test public void softReferenceWithoutAttachment() { final Reference reference = new SoftReference("referent"); assertReference(reference, "referent", null, null); } @Test public void nullSoftReference() throws Exception { final Reference reference = new SoftReference(null, Integer.valueOf(0)); assertReference(reference, null, Integer.valueOf(0), null); } @Test public void softReferenceWithReferenceQueue() throws Exception { final ReferenceQueue> referenceQueue = new ReferenceQueue>(); final Collection collection = new ArrayList(); final Reference, String> reference = new SoftReference, String>(collection, "collection", referenceQueue); assertReference(reference, collection, "collection", null); } @Test public void softReferenceWithReaper() throws Exception { final Thing thing = new Thing(); final TestReaper reaper = new TestReaper(); final Reference reference = new SoftReference(thing, null, reaper); assertReference(reference, thing, null, reaper); } @Override Reference createReference(T value, A attachment) { return new SoftReference(value, attachment); } @Override Type getTestedReferenceType() { return Type.SOFT; } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/StrongReferenceTestCase.java000066400000000000000000000042041257205723500315620ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import org.jboss.modules.ref.Reference.Type; import org.junit.Test; /** * Test for {@link StrongReference}. * * @author Flavia Rainone */ public class StrongReferenceTestCase extends AbstractReferenceTest{ @Test public void plainStrongReference() { final Reference reference = new StrongReference("referent", "attachment"); assertReference(reference, "referent", "attachment"); } @Test public void noAttachmentReference() { final Reference reference = new StrongReference("noAttachmentReference"); assertReference(reference, "noAttachmentReference", null); } @Test public void nullReference() { final Reference reference = new StrongReference(null, "attachment of null reference"); assertReference(reference, null, "attachment of null reference"); } @Test public void nullReferenceWithoutAttachment() { final Reference reference = new StrongReference(null); assertReference(reference, null, null); } @Override Reference createReference(T value, A attachment) { return new StrongReference(value, attachment); } @Override Type getTestedReferenceType() { return Type.STRONG; } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/Thing.java000066400000000000000000000020101257205723500260750ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; /** * @author David M. Lloyd */ public final class Thing { private final String blah = "blah!"; private final int boo = 123; public String getBlah() { return blah; } public int getBoo() { return boo; } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/WeakReferenceTestCase.java000066400000000000000000000061431257205723500312010ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref; import static org.junit.Assert.assertSame; import java.lang.ref.ReferenceQueue; import java.util.ArrayList; import java.util.Collection; import org.jboss.modules.ref.Reference.Type; import org.jboss.modules.ref.util.TestReaper; import org.junit.Test; /** * Test for {@link WeakReference}. * * @author Flavia Rainone */ public class WeakReferenceTestCase extends AbstractReapableReferenceTest { @Test public void plainWeakReference() { final Reference reference = new WeakReference("referent", "attachment"); assertReference(reference, "referent", "attachment", null); } @Test public void weakReferenceWithoutAttachment() { final Reference reference = new WeakReference("referent"); assertReference(reference, "referent", null, null); } @Test public void nullWeakReference() throws Exception { final Reference reference = new WeakReference(null, Integer.valueOf(0)); assertReference(reference, null, Integer.valueOf(0)); } @Test public void weakReferenceWithReferenceQueue() throws Exception { final ReferenceQueue> referenceQueue = new ReferenceQueue>(); Collection collection = new ArrayList(); final Reference, String> reference = new WeakReference, String>(collection, "collection", referenceQueue); assertReference(reference, collection, "collection", null); collection = null; System.gc(); assertSame(reference, referenceQueue.remove(300)); } @Test public void weakReferenceWithReaper() throws Exception { Thing thing = new Thing(); final TestReaper reaper = new TestReaper(); final Reference reference = new WeakReference(thing, null, reaper); assertReference(reference, thing, null, reaper); thing = null; System.gc(); assertSame(reference, reaper.getReapedReference()); } @Override Reference createReference(T value, A attachment) { return new WeakReference(value, attachment); } @Override Type getTestedReferenceType() { return Type.WEAK; } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/util/000077500000000000000000000000001257205723500251455ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/util/Assert.java000066400000000000000000000067771257205723500272720ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import org.jboss.modules.ref.Reaper; import org.jboss.modules.ref.Reference; import org.jboss.modules.ref.Reference.Type; /** * Assertion methods used by reference tests. * * @author Flavia Rainone */ public class Assert { /** * Assert that {@code reference} contains {@code referent}, {@code attachment}, and that its type is {@code type}. * * @param the type of referent * @param the type of attachment * @param reference the reference that needs to be checked * @param referent the expected content for {@code reference} * @param attachment the expected attachment contained in {@code reference} * @param type the expected type of {@code reference} */ public static final void assertReference(Reference reference, T referent, A attachment, Type type) { assertEquals(referent, reference.get()); assertEquals(attachment, reference.getAttachment()); assertSame(type, reference.getType()); assertNotNull(reference.toString()); // make sure that no exception is thrown and that null is never returned } /** * Assert that {@code reference} contains {@code referent}, {@code attachment}, and that its type is {@code type}. * Also asserts that {@code reaper} is the reaper used by {@code referent}. *

    * Call this method only for {@link org.jboss.msc.ref.Reapable Reapable} references. This method assumes that * {@code reference} has a method called {@code getReaper} that will return the reaper. * * @param the type of referent * @param the type of attachment * @param reference the {@code Reapable} reference that needs to be checked * @param referent the expected content for {@code reference} * @param attachment the expected attachment contained in {@code reference} * @param type the expected type of {@code reference} * @param reaper the expected reaper */ public static final void assertReference(Reference reference, T referent, A attachment, Type type, Reaper reaper) { assertReference(reference, referent, attachment, type); try { assertEquals(reaper, reference.getClass().getMethod("getReaper").invoke(reference)); } catch (NoSuchMethodException e) { fail("Can't find getReaper method at clas " + reference.getClass()); } catch (RuntimeException e) { throw e; } catch (Exception e) { fail(e.getMessage()); } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/ref/util/TestReaper.java000066400000000000000000000045311257205723500300710ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.ref.util; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.jboss.modules.ref.Reaper; import org.jboss.modules.ref.Reference; /** * Reaper used by tests. * * @author Flavia Rainone * */ public class TestReaper implements Reaper, Future> { private Reference reaped; private final CountDownLatch countDownLatch = new CountDownLatch(1); @Override public void reap(Reference reference) { reaped = reference; countDownLatch.countDown(); } public Reference getReapedReference() throws InterruptedException, ExecutionException { return get(); } @Override public boolean cancel(boolean mayInterruptIfRunning) { return false; } @Override public boolean isCancelled() { return false; } @Override public boolean isDone() { return reaped != null; } @Override public Reference get() throws InterruptedException, ExecutionException { try { return get(30l, TimeUnit.SECONDS); } catch (TimeoutException e) { throw new RuntimeException("Could not get reaped in 30 second timeout."); } } @Override public Reference get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { countDownLatch.await(timeout, unit); return reaped; } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/000077500000000000000000000000001257205723500243735ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/BarImpl.java000066400000000000000000000013761257205723500265730ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; public class BarImpl { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/ClassA.java000066400000000000000000000014561257205723500264120ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * @author John E. Bailey */ public class ClassA extends ClassB { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/ClassB.java000066400000000000000000000014371257205723500264120ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * @author John E. Bailey */ public class ClassB { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/ClassC.java000066400000000000000000000014561257205723500264140ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * @author John E. Bailey */ public class ClassC extends ClassD { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/ClassD.java000066400000000000000000000014371257205723500264140ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * @author John E. Bailey */ public class ClassD { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/ImportedClass.java000066400000000000000000000014711257205723500300120ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * ImportedClass - * * @author John Bailey */ public class ImportedClass { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/ImportedInterface.java000066400000000000000000000015621257205723500306460ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * ImportedInterface - * * @author Flavia Rainone */ public class ImportedInterface { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/JAXPCaller.java000066400000000000000000000123771257205723500271350ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; import javax.xml.XMLConstants; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.events.DTD; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; public class JAXPCaller { public Document document() { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { return factory.newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw new IllegalStateException(); } } public DocumentBuilderFactory documentFactory() { return DocumentBuilderFactory.newInstance(); } public DocumentBuilder documentBuilder() { try { return DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new IllegalStateException(); } } public SchemaFactory schemaFactory() { return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); } public Schema schema() { try { return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(); } catch (SAXException e) { throw new IllegalStateException(); } } public XMLReader xmlReader() { try { return XMLReaderFactory.createXMLReader(); } catch (SAXException e) { throw new IllegalStateException(); } } public SAXParserFactory saxParserFactory() { return SAXParserFactory.newInstance(); } public SAXParser saxParser() { try { return SAXParserFactory.newInstance().newSAXParser(); } catch (Exception e) { throw new IllegalStateException(); } } public XPathFactory xpathFactory() { return XPathFactory.newInstance(); } public XPath xpath() { try { return XPathFactory.newInstance().newXPath(); } catch (Exception e) { throw new IllegalStateException(); } } public TransformerFactory transformerFactory() { return TransformerFactory.newInstance(); } public Transformer transformer() { try { return transformerFactory().newTransformer(); } catch (Exception e) { throw new IllegalStateException(); } } public TransformerHandler transformerHandler() { try { return ((SAXTransformerFactory)transformerFactory()).newTransformerHandler(); } catch (Exception e) { throw new IllegalStateException(); } } public XMLEventFactory eventFactory() { return XMLEventFactory.newInstance(); } public DTD eventDTD() { try { return eventFactory().createDTD("blah"); } catch (Exception e) { throw new IllegalStateException(e); } } public XMLInputFactory inputFactory() { return XMLInputFactory.newInstance(); } public String inputProperty() { return String.valueOf(inputFactory().getProperty("javax.xml.stream.reporter")); } public XMLOutputFactory outputFactory() { return XMLOutputFactory.newInstance(); } public String outputProperty() { return String.valueOf(outputFactory().getProperty("javax.xml.stream.isRepairingNamespaces")); } public DatatypeFactory datatypeFactory() { try { return DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException e) { throw new IllegalStateException(); } } public Duration duration() { return datatypeFactory().newDuration(1); } public static void main(String[] args) { // for main test, do nothing } }jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/QuxBar.java000066400000000000000000000013741257205723500264450ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; public class QuxBar { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/QuxFoo.java000066400000000000000000000013751257205723500264650ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; public class QuxFoo { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/QuxImpl.java000066400000000000000000000013761257205723500266440ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; public class QuxImpl { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/test/TestClass.java000066400000000000000000000014441257205723500271460ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.test; /** * @author John Bailey */ public class TestClass { } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/util/000077500000000000000000000000001257205723500243715ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/util/ModulesTestBase.java000066400000000000000000000131661257205723500303060ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.util; import org.jboss.modules.DependencySpec; import org.jboss.modules.Module; import org.jboss.modules.ModuleClassLoader; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoadException; import org.jboss.modules.ModuleLoader; import org.jboss.modules.ModuleSpec; import org.jboss.modules.filter.PathFilter; import org.jboss.modules.filter.PathFilters; import org.junit.Before; import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; /** * Test low level modules use cases. * * @author Thomas.Diesler@jboss.com * @since 15-Sep-2010 */ public abstract class ModulesTestBase { private ModuleLoaderSupport moduleLoader; @Before public void setUp() throws Exception { moduleLoader = new ModuleLoaderSupport("default"); } protected ModuleLoaderSupport getModuleLoader() { return moduleLoader; } protected void addModuleSpec(ModuleSpec moduleSpec) { moduleLoader.addModuleSpec(moduleSpec); } protected Module loadModule(ModuleIdentifier identifier) throws ModuleLoadException { return moduleLoader.loadModule(identifier); } protected PathFilter getPathFilter(Class... classes) { Set paths = getFilterPaths(classes); return PathFilters.in(paths); } protected Set getFilterPaths(Class... classes) { Set paths = new HashSet(); for (Class clazz : classes) { paths.add(getPathForClassName(clazz.getName())); } return Collections.unmodifiableSet(paths); } protected String getPathForClassName(String className) { className = className.substring(0, className.lastIndexOf('.')); className = className.replace('.', '/'); return className; } protected void assertLoadClass(ModuleIdentifier identifier, String className) throws Exception { Class clazz = loadClass(identifier, className); assertNotNull(clazz); } protected void assertLoadClass(ModuleIdentifier identifier, String className, ModuleIdentifier exporterId) throws Exception { Class clazz = loadClass(identifier, className); ClassLoader wasClassLoader = clazz.getClassLoader(); if (exporterId == null && wasClassLoader == null) { return; } ModuleClassLoader expClassLoader = loadModule(exporterId).getClassLoader(); assertEquals(expClassLoader, wasClassLoader); } protected void assertLoadClassFail(ModuleIdentifier identifier, String className) throws Exception { try { Class clazz = loadClass(identifier, className); assertNotNull("ClassNotFoundException expected for [" + className + "], but was: " + clazz, clazz); fail("ClassNotFoundException expected for [" + className + "], but was loaded from: " + clazz.getClassLoader()); } catch (ClassNotFoundException ex) { // expected } catch (NoClassDefFoundError ex) { // expected } } protected Class loadClass(ModuleIdentifier identifier, String className) throws Exception { // ClassLoader#resolveClass() only links the class; it doesn't necessarily force it to be initialized. // To initialize the class you can do Class.forName(name, true, classLoader) ModuleClassLoader classLoader = loadModule(identifier).getClassLoader(); Class clazz = Class.forName(className, true, classLoader); return clazz; } protected URL getResource(ModuleIdentifier identifier, String resourcePath) throws Exception { ModuleClassLoader classLoader = loadModule(identifier).getClassLoader(); return classLoader.getResource(resourcePath); } static class ModuleLoaderSupport extends ModuleLoader { private String loaderName; private Map modules = new HashMap(); ModuleLoaderSupport(String loaderName) { this.loaderName = loaderName; } void addModuleSpec(ModuleSpec moduleSpec) { modules.put(moduleSpec.getModuleIdentifier(), moduleSpec); } @Override protected ModuleSpec findModule(ModuleIdentifier identifier) throws ModuleLoadException { ModuleSpec moduleSpec = modules.get(identifier); return moduleSpec; } @Override protected void setAndRelinkDependencies(Module module, List dependencies) throws ModuleLoadException { super.setAndRelinkDependencies(module, dependencies); } @Override public String toString() { return "ModuleLoaderSupport[" + loaderName + "]"; } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/util/TestModuleLoader.java000066400000000000000000000040031257205723500304450ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.util; import org.jboss.modules.Module; import org.jboss.modules.ModuleIdentifier; import org.jboss.modules.ModuleLoadException; import org.jboss.modules.ModuleLoader; import org.jboss.modules.ModuleSpec; import java.util.HashMap; import java.util.Map; /** * Test module loader that allows for modules specs to be added at runtime and it will only load modules from the * provided specs. * * @author John E. Bailey */ public class TestModuleLoader extends ModuleLoader { private final Map moduleSpecs = new HashMap(); protected Module preloadModule(final ModuleIdentifier identifier) throws ModuleLoadException { return super.preloadModule(identifier); } @Override protected ModuleSpec findModule(ModuleIdentifier moduleIdentifier) throws ModuleLoadException { final ModuleSpec moduleSpec = moduleSpecs.get(moduleIdentifier); if(moduleSpec == null) throw new ModuleLoadException("No module spec found for module " + moduleIdentifier); return moduleSpec; } public void addModuleSpec(final ModuleSpec moduleSpec) { moduleSpecs.put(moduleSpec.getModuleIdentifier(), moduleSpec); } public String toString() { return "test@" + System.identityHashCode(this); } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/util/TestResourceLoader.java000066400000000000000000000206261257205723500310200ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.util; import org.jboss.modules.AbstractResourceLoader; import org.jboss.modules.ClassSpec; import org.jboss.modules.PackageSpec; import org.jboss.modules.Resource; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.jar.Attributes; import java.util.jar.Manifest; import static junit.framework.Assert.assertTrue; import static org.jboss.modules.util.Util.getClassBytes; /** * A test resource loader that simple retrieves resources frm maps. This allows tests to build * arbitrary modules with arbitrary content without having to have the module on disk. * * @author John E. Bailey */ public class TestResourceLoader extends AbstractResourceLoader { private final Map classSpecs = new HashMap(); private final Map resources = new HashMap(); private final Set paths = new HashSet(); private Manifest manifest; public String getRootName() { return "test"; } @Override public ClassSpec getClassSpec(final String fileName) throws IOException { final Map classSpecs = this.classSpecs; return classSpecs.get(fileName); } void addClassSpec(final String name, final ClassSpec classSpec) { final Map classSpecs = this.classSpecs; classSpecs.put(name.replace('.', '/') + ".class", classSpec); addPaths(getPathFromClassName(name)); } @Override public PackageSpec getPackageSpec(final String name) throws IOException { return getPackageSpec(name, getManifest(), null); } private Manifest getManifest() throws IOException { if(manifest != null) return manifest; final Resource manifestResource = getResource("META-INF/MANIFEST.MF"); if(manifestResource == null) return null; final InputStream manifestStream = manifestResource.openStream(); try { manifest = new Manifest(manifestStream); } finally { if(manifestStream != null) manifestStream.close(); } return manifest; } private static String getDefinedAttribute(Attributes.Name name, Attributes entryAttribute, Attributes mainAttribute) { final String value = entryAttribute == null ? null : entryAttribute.getValue(name); return value == null ? mainAttribute == null ? null : mainAttribute.getValue(name) : value; } @Override public Resource getResource(final String name) { String resourceName = name; if (resourceName.startsWith("/")) resourceName = resourceName.substring(1); final Map resources = this.resources; return resources.get(resourceName); } void addResource(final String name, final Resource resource) { final Map resources = this.resources; resources.put(name, resource); addPaths(getPathFromResourceName(name)); } private void addPaths(String path) { final String[] parts = path.split("/"); String current = ""; for(String part : parts) { current += part; paths.add(current); current += "/"; } } @Override public String getLibrary(String name) { return null; } @Override public Collection getPaths() { return paths; } private String getPathFromResourceName(final String resourcePath) { int idx = resourcePath.lastIndexOf('/'); final String path = idx > -1 ? resourcePath.substring(0, idx) : ""; return path; } private String getPathFromClassName(final String className) { int idx = className.lastIndexOf('.'); return idx > -1 ? className.substring(0, idx).replace('.', '/') : ""; } public static TestResourceLoaderBuilder build() { return new TestResourceLoaderBuilder(); } public static class TestResourceLoaderBuilder { private final TestResourceLoader resourceLoader = new TestResourceLoader(); public TestResourceLoader create() { return resourceLoader; } public TestResourceLoaderBuilder addResource(final String name, final URL resourceUrl) { addResource(name, new Resource() { @Override public String getName() { return name; } @Override public URL getURL() { return resourceUrl; } @Override public InputStream openStream() throws IOException { return resourceUrl.openStream(); } @Override public long getSize() { return 0L; } }); return this; } public TestResourceLoaderBuilder addResource(final String name, final File resource) throws MalformedURLException { final URL url = resource.toURI().toURL(); addResource(name, new Resource() { @Override public String getName() { return name; } @Override public URL getURL() { return url; } @Override public InputStream openStream() throws IOException { return new FileInputStream(resource); } @Override public long getSize() { return resource.length(); } }); return this; } public TestResourceLoaderBuilder addResource(final String name, final Resource resource) { final TestResourceLoader resourceLoader = this.resourceLoader; resourceLoader.addResource(name, resource); return this; } public TestResourceLoaderBuilder addResources(final File base) throws Exception { addResources("", base); return this; } private void addResources(final String pathBase, final File base) throws Exception { assertTrue(base.isDirectory()); final File[] children = base.listFiles(); for (File child : children) { final String childPath = pathBase + child.getName(); if (child.isDirectory()) { addResources(childPath + "/", child); } else { addResource(childPath, child); } } } public TestResourceLoaderBuilder addClass(final Class aClass) throws Exception { final ClassSpec classSpec = new ClassSpec(); classSpec.setCodeSource(aClass.getProtectionDomain().getCodeSource()); final byte[] classBytes = getClassBytes(aClass); classSpec.setBytes(classBytes); addClassSpec(aClass.getName(), classSpec); return this; } public TestResourceLoaderBuilder addClasses(final Class... classes) throws Exception { for(Class aClass : classes) { addClass(aClass); } return this; } public TestResourceLoaderBuilder addClassSpec(final String name, final ClassSpec classSpec) { final TestResourceLoader resourceLoader = this.resourceLoader; resourceLoader.addClassSpec(name, classSpec); return this; } } } jboss-modules-1.4.4.Final/src/test/java/org/jboss/modules/util/Util.java000066400000000000000000000053141257205723500261540ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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. */ package org.jboss.modules.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; /** * Utility class providing commonly used test utilities. * * @author John E. Bailey */ public class Util { public static byte[] readBytes(final InputStream is) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); try { byte[] buff = new byte[1024]; int read; while((read = is.read(buff)) > -1) { os.write(buff, 0, read); } } finally { is.close(); } return os.toByteArray(); } public static URL getResource(final Class baseClass, final String path) throws Exception { final URL url = baseClass.getClassLoader().getResource(path); return url; } public static File getResourceFile(final Class baseClass, final String path) throws Exception { return new File(getResource(baseClass, path).toURI()); } public static List toList(Enumeration enumeration) { final List list = new ArrayList(); while(enumeration.hasMoreElements()) { list.add(enumeration.nextElement()); } return list; } public static byte[] getClassBytes(final Class aClass) throws Exception { final String resourcePath = getResourceNameOfClass(aClass); final File classFile = Util.getResourceFile(aClass, resourcePath); byte[] classBytes = Util.readBytes(new FileInputStream(classFile)); return classBytes; } public static String getResourceNameOfClass(final Class aClass) throws IllegalArgumentException { final String nameAsResourcePath = aClass.getName().replace('.', '/'); final String resourceName = nameAsResourcePath + ".class"; return resourceName; } } jboss-modules-1.4.4.Final/src/test/resources/000077500000000000000000000000001257205723500211265ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/000077500000000000000000000000001257205723500242435ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/file1.txt000066400000000000000000000000001257205723500257720ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/org/000077500000000000000000000000001257205723500250325ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/org/jboss/000077500000000000000000000000001257205723500261525ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/org/jboss/modules/000077500000000000000000000000001257205723500276225ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/org/jboss/modules/test/000077500000000000000000000000001257205723500306015ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/class-resources/org/jboss/modules/test/file2.txt000066400000000000000000000000001257205723500323310ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/000077500000000000000000000000001257205723500221055ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/fileresourceloader/000077500000000000000000000000001257205723500257635ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/fileresourceloader/META-INF/000077500000000000000000000000001257205723500271235ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/fileresourceloader/META-INF/MANIFEST.MF000066400000000000000000000004421257205723500305550ustar00rootroot00000000000000Manifest-Version: 1.0 Specification-Title: MODULES-89 Name: org/jboss/modules/test/ Specification-Title: JBoss Modules Test Classes Specification-Version: 0.1 Specification-Vendor: JBoss Implementation-Title: org.jboss.modules.test Implementation-Version: 1.0 Implementation-Vendor: JBoss jboss-modules-1.4.4.Final/src/test/resources/test/fileresourceloader/nested/000077500000000000000000000000001257205723500272455ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/fileresourceloader/nested/nested.txt000066400000000000000000000000201257205723500312600ustar00rootroot00000000000000nested test filejboss-modules-1.4.4.Final/src/test/resources/test/fileresourceloader/test.txt000066400000000000000000000000111257205723500274730ustar00rootroot00000000000000test filejboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/000077500000000000000000000000001257205723500256155ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/000077500000000000000000000000001257205723500271425ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/a/000077500000000000000000000000001257205723500273625ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/a/shared/000077500000000000000000000000001257205723500306305ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/a/shared/module.xml000066400000000000000000000016731257205723500326460ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/a/unique/000077500000000000000000000000001257205723500306705ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/a/unique/module.xml000066400000000000000000000016661257205723500327100ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/b/000077500000000000000000000000001257205723500273635ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/b/shared/000077500000000000000000000000001257205723500306315ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/b/shared/module.xml000066400000000000000000000016731257205723500326470ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/b/unique/000077500000000000000000000000001257205723500306715ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/add-ons/b/unique/module.xml000066400000000000000000000016661257205723500327110ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/000077500000000000000000000000001257205723500271145ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/base/000077500000000000000000000000001257205723500300265ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/base/shared/000077500000000000000000000000001257205723500312745ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/base/shared/module.xml000066400000000000000000000016761257205723500333150ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/base/unique/000077500000000000000000000000001257205723500313345ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/base/unique/module.xml000066400000000000000000000016741257205723500333530ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/mid/000077500000000000000000000000001257205723500276655ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/mid/shared/000077500000000000000000000000001257205723500311335ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/mid/shared/module.xml000066400000000000000000000016751257205723500331530ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/mid/unique/000077500000000000000000000000001257205723500311735ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/mid/unique/module.xml000066400000000000000000000016721257205723500332100ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/top/000077500000000000000000000000001257205723500277165ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/top/shared/000077500000000000000000000000001257205723500311645ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/top/shared/module.xml000066400000000000000000000016751257205723500332040ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/top/unique/000077500000000000000000000000001257205723500312245ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/layers/top/unique/module.xml000066400000000000000000000016721257205723500332410ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/user/000077500000000000000000000000001257205723500265735ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/user/shared/000077500000000000000000000000001257205723500300415ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/user/shared/module.xml000066400000000000000000000016761257205723500320620ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/user/unique/000077500000000000000000000000001257205723500301015ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/layeredmodulepath/user/unique/module.xml000066400000000000000000000016741257205723500321200ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/000077500000000000000000000000001257205723500261545ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/000077500000000000000000000000001257205723500271165ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/000077500000000000000000000000001257205723500302565ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services/000077500000000000000000000000001257205723500321015ustar00rootroot00000000000000javax.xml.datatype.DatatypeFactory000066400000000000000000000013471257205723500405760ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeDatatypeFactory javax.xml.parsers.DocumentBuilderFactory000066400000000000000000000013561257205723500417540ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeDocumentBuilderFactory javax.xml.parsers.SAXParserFactory000066400000000000000000000013501257205723500404710ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeSAXParserFactory javax.xml.stream.XMLEventFactory000066400000000000000000000013471257205723500401450ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeXMLEventFactory javax.xml.stream.XMLInputFactory000066400000000000000000000013471257205723500401630ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeXMLInputFactory javax.xml.stream.XMLOutputFactory000066400000000000000000000013501257205723500403560ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeXMLOutputFactory javax.xml.transform.TransformerFactory000066400000000000000000000013521257205723500415210ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeTransformerFactory javax.xml.validation.SchemaFactory000066400000000000000000000013451257205723500405400ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeSchemaFactory javax.xml.xpath.XPathFactory000066400000000000000000000013441257205723500373550ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeXPathFactory org.xml.sax.driver000066400000000000000000000013411257205723500354160ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/jaxp/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # org.jboss.modules.JAXPModuleTest$FakeXMLReader jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootOne/000077500000000000000000000000001257205723500276015ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootOne/META-INF/000077500000000000000000000000001257205723500307415ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootOne/META-INF/MANIFEST.MF000066400000000000000000000004021257205723500323670ustar00rootroot00000000000000Manifest-Version: 1.0 Name: org/jboss/modules/test/ Specification-Title: JBoss Modules Test Classes Specification-Version: 0.1 Specification-Vendor: JBoss Implementation-Title: org.jboss.modules.test Implementation-Version: 1.0 Implementation-Vendor: JBoss jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootOne/nested/000077500000000000000000000000001257205723500310635ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootOne/nested/nested.txt000066400000000000000000000000201257205723500330760ustar00rootroot00000000000000nested test filejboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootOne/test.txt000066400000000000000000000000111257205723500313110ustar00rootroot00000000000000test filejboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootTwo/000077500000000000000000000000001257205723500276315ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootTwo/nested/000077500000000000000000000000001257205723500311135ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootTwo/nested/nested.txt000066400000000000000000000000201257205723500331260ustar00rootroot00000000000000nested test filejboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootTwo/nestedTwo/000077500000000000000000000000001257205723500316055ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootTwo/nestedTwo/nested.txt000066400000000000000000000000171257205723500336260ustar00rootroot00000000000000nested file twojboss-modules-1.4.4.Final/src/test/resources/test/modulecontentloader/rootTwo/testTwo.txt000066400000000000000000000000101257205723500320320ustar00rootroot00000000000000test twojboss-modules-1.4.4.Final/src/test/resources/test/repo/000077500000000000000000000000001257205723500230525ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/000077500000000000000000000000001257205723500240315ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/bad-deps/000077500000000000000000000000001257205723500255105ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/bad-deps/main/000077500000000000000000000000001257205723500264345ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/bad-deps/main/module.xml000066400000000000000000000017251257205723500304500ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-A/000077500000000000000000000000001257205723500267445ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-A/main/000077500000000000000000000000001257205723500276705ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-A/main/module.xml000066400000000000000000000020271257205723500317000ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-B/000077500000000000000000000000001257205723500267455ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-B/main/000077500000000000000000000000001257205723500276715ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-B/main/module.xml000066400000000000000000000017511257205723500317040ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-C/000077500000000000000000000000001257205723500267465ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-C/main/000077500000000000000000000000001257205723500276725ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-C/main/module.xml000066400000000000000000000020271257205723500317020ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-D/000077500000000000000000000000001257205723500267475ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-D/main/000077500000000000000000000000001257205723500276735ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/circular-deps-D/main/module.xml000066400000000000000000000017511257205723500317060ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs-jaxb-provider/000077500000000000000000000000001257205723500277325ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs-jaxb-provider/main/000077500000000000000000000000001257205723500306565ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs-jaxb-provider/main/META-INF/000077500000000000000000000000001257205723500320165ustar00rootroot00000000000000000077500000000000000000000000001257205723500335625ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs-jaxb-provider/main/META-INF/servicesjavax.ws.rs.ext.Providers000066400000000000000000000013411257205723500404430ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs-jaxb-provider/main/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # jaxrs.jaxb.providers.P0 jaxrs.jaxb.providers.P1jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs-jaxb-provider/main/module.xml000066400000000000000000000017421257205723500326710ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs/000077500000000000000000000000001257205723500251605ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs/main/000077500000000000000000000000001257205723500261045ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs/main/META-INF/000077500000000000000000000000001257205723500272445ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs/main/META-INF/services/000077500000000000000000000000001257205723500310675ustar00rootroot00000000000000javax.ws.rs.ext.Providers000066400000000000000000000013411257205723500356710ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs/main/META-INF/services# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # jaxrs.core.providers.P0 jaxrs.core.providers.P1jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/jaxrs/main/module.xml000066400000000000000000000020271257205723500301140ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/maven/000077500000000000000000000000001257205723500251375ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/maven/main/000077500000000000000000000000001257205723500260635ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/maven/main/module.xml000077500000000000000000000020421257205723500300730ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/maven/non-main/000077500000000000000000000000001257205723500266535ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/maven/non-main/module.xml000066400000000000000000000021611257205723500306620ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/service/000077500000000000000000000000001257205723500254715ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/service/main/000077500000000000000000000000001257205723500264155ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/service/main/META-INF/000077500000000000000000000000001257205723500275555ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/service/main/META-INF/services/000077500000000000000000000000001257205723500314005ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/service/main/META-INF/services/dummy000066400000000000000000000012671257205723500324640ustar00rootroot00000000000000# # JBoss, Home of Professional Open Source. # Copyright 2014 Red Hat, Inc., and individual contributors # as indicated by the @author tags. # # 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. # dummyjboss-modules-1.4.4.Final/src/test/resources/test/repo/test/service/main/module.xml000066400000000000000000000017251257205723500304310ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/test/000077500000000000000000000000001257205723500250105ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/test/main/000077500000000000000000000000001257205723500257345ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/test/main/module.xml000066400000000000000000000017561257205723500277540ustar00rootroot00000000000000 jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/with-deps/000077500000000000000000000000001257205723500257355ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/with-deps/main/000077500000000000000000000000001257205723500266615ustar00rootroot00000000000000jboss-modules-1.4.4.Final/src/test/resources/test/repo/test/with-deps/main/module.xml000066400000000000000000000017301257205723500306710ustar00rootroot00000000000000