This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch struts-2-4 in repository https://gitbox.apache.org/repos/asf/struts.git
commit 8e57f952f04125e5454990d9a135488a85b0c508 Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Sat Mar 31 19:55:01 2018 +0200 Drops java8-support plugin --- .../struts2/convention/DefaultClassFinder.java} | 17 +- .../PackageBasedActionConfigBuilder.java | 1 - plugins/java8-support/README.adoc | 11 - plugins/java8-support/pom.xml | 60 --- .../convention/Java8ClassFinderFactory.java | 48 -- .../java8-support/src/main/resources/LICENSE.txt | 174 ------ .../java8-support/src/main/resources/NOTICE.txt | 5 - .../src/main/resources/struts-plugin.xml | 33 -- plugins/java8-support/src/site/site.xml | 57 -- plugins/pom.xml | 1 - .../xwork2/util/finder/DefaultClassFinder.java | 582 --------------------- 11 files changed, 7 insertions(+), 982 deletions(-) diff --git a/plugins/java8-support/src/main/java/org/apache/struts2/convention/Java8ClassFinder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java similarity index 97% rename from plugins/java8-support/src/main/java/org/apache/struts2/convention/Java8ClassFinder.java rename to plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java index 2d49e18..f1a5e34 100644 --- a/plugins/java8-support/src/main/java/org/apache/struts2/convention/Java8ClassFinder.java +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/DefaultClassFinder.java @@ -55,12 +55,9 @@ import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; -/** - * Copy of {@link com.opensymphony.xwork2.util.finder.DefaultClassFinder} with proper support for Java8 - */ -public class Java8ClassFinder implements ClassFinder { +public class DefaultClassFinder implements ClassFinder { - private static final Logger LOG = LoggerFactory.getLogger(Java8ClassFinder.class); + private static final Logger LOG = LoggerFactory.getLogger(DefaultClassFinder.class); private final Map<String, List<Info>> annotated = new HashMap<String, List<Info>>(); private final Map<String, ClassInfo> classInfos = new LinkedHashMap<String, ClassInfo>(); @@ -71,7 +68,7 @@ public class Java8ClassFinder implements ClassFinder { private ClassLoaderInterface classLoaderInterface; private FileManager fileManager; - public Java8ClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) { + public DefaultClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) { this.classLoaderInterface = classLoaderInterface; this.extractBaseInterfaces = extractBaseInterfaces; this.fileManager = ActionContext.getContext().getInstance(FileManagerFactory.class).getFileManager(); @@ -109,11 +106,11 @@ public class Java8ClassFinder implements ClassFinder { } } - public Java8ClassFinder(Class... classes){ + public DefaultClassFinder(Class... classes){ this(Arrays.asList(classes)); } - public Java8ClassFinder(List<Class> classes){ + public DefaultClassFinder(List<Class> classes){ this.classLoaderInterface = null; List<Info> infos = new ArrayList<Info>(); List<Package> packages = new ArrayList<Package>(); @@ -407,7 +404,7 @@ public class Java8ClassFinder implements ClassFinder { } } else if (LOG.isDebugEnabled()) LOG.debug("Unable to read [#0]", location.toExternalForm()); - + return Collections.emptyList(); } @@ -423,7 +420,7 @@ public class Java8ClassFinder implements ClassFinder { className = className.replaceFirst(".class$", ""); //war files are treated as .jar files, so takeout WEB-INF/classes - className = StringUtils.removeStart(className, "WEB-INF/classes/"); + className = StringUtils.removeStart(className, "WEB-INF/classes/"); className = className.replace('/', '.'); classNames.add(className); diff --git a/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java b/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java index d1ad0c0..7c04102 100644 --- a/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java +++ b/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java @@ -39,7 +39,6 @@ import com.opensymphony.xwork2.util.WildcardHelper; import com.opensymphony.xwork2.util.classloader.ReloadingClassLoader; import com.opensymphony.xwork2.util.finder.ClassFinder; import com.opensymphony.xwork2.util.finder.ClassFinderFactory; -import com.opensymphony.xwork2.util.finder.DefaultClassFinder; import com.opensymphony.xwork2.util.finder.ClassLoaderInterface; import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate; import com.opensymphony.xwork2.util.finder.Test; diff --git a/plugins/java8-support/README.adoc b/plugins/java8-support/README.adoc deleted file mode 100644 index beae27c..0000000 --- a/plugins/java8-support/README.adoc +++ /dev/null @@ -1,11 +0,0 @@ -= Struts 2 Java 8 Support plugin - -This plugin aims to add support for Java 8 specific features. -As Struts 2 core targets Java 6/7 and some features won't work and they have to be adjusted. -Below is a list of features supported by this plugin - -== Supported Java 8 features -- Lambada expressions in actions when using them with the Convention plugin - -== Installation -Just drop this plugin into `WEB-INF/lib` folder or add it as Maven dependency diff --git a/plugins/java8-support/pom.xml b/plugins/java8-support/pom.xml deleted file mode 100644 index 7bb9b81..0000000 --- a/plugins/java8-support/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.apache.struts</groupId> - <artifactId>struts2-plugins</artifactId> - <version>2.4.0-SNAPSHOT</version> - </parent> - - <artifactId>struts2-java8-support-plugin</artifactId> - <packaging>jar</packaging> - <name>Struts 2 Java 8 support plugin</name> - - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <Bundle-Activator>org.apache.struts2.osgi.StrutsActivator</Bundle-Activator> - <manifestLocation>META-INF</manifestLocation> - </instructions> - </configuration> - </plugin> - </plugins> - - </build> - - <dependencies> - <dependency> - <groupId>org.apache.struts.xwork</groupId> - <artifactId>xwork-core</artifactId> - <exclusions> - <exclusion> - <groupId>asm</groupId> - <artifactId>asm</artifactId> - </exclusion> - <exclusion> - <groupId>asm</groupId> - <artifactId>asm-commons</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.ow2.asm</groupId> - <artifactId>asm</artifactId> - </dependency> - <dependency> - <groupId>org.ow2.asm</groupId> - <artifactId>asm-commons</artifactId> - </dependency> - </dependencies> - - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - </properties> -</project> diff --git a/plugins/java8-support/src/main/java/org/apache/struts2/convention/Java8ClassFinderFactory.java b/plugins/java8-support/src/main/java/org/apache/struts2/convention/Java8ClassFinderFactory.java deleted file mode 100644 index 3ab5f9e..0000000 --- a/plugins/java8-support/src/main/java/org/apache/struts2/convention/Java8ClassFinderFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-2003,2009 The Apache Software Foundation. - * - * 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.apache.struts2.convention; - -import com.opensymphony.xwork2.util.finder.ClassFinder; -import com.opensymphony.xwork2.util.finder.ClassFinderFactory; -import com.opensymphony.xwork2.util.finder.ClassLoaderInterface; -import com.opensymphony.xwork2.util.finder.Test; -import com.opensymphony.xwork2.util.logging.Logger; -import com.opensymphony.xwork2.util.logging.LoggerFactory; - -import java.net.URL; -import java.util.Collection; -import java.util.Set; - -public class Java8ClassFinderFactory implements ClassFinderFactory { - - private static final Logger LOG = LoggerFactory.getLogger(Java8ClassFinderFactory.class); - - public Java8ClassFinderFactory() { - try { - LOG.trace("Checking if ASM5 is on the classpath...."); - Class.forName("org.objectweb.asm.MethodVisitor"); - LOG.trace("Proper version of ASM5 is in use!"); - } catch (ClassNotFoundException e) { - LOG.warn("ASM5 is missing or older version is used! If you use Maven, please exclude asm.jar and asm-commons.jar version 3 from xwork!"); - } - } - - public ClassFinder buildClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) { - LOG.debug("Creating new instance of Java8ClassFinder"); - return new Java8ClassFinder(classLoaderInterface, urls, extractBaseInterfaces, protocols, classNameFilter); - } - -} diff --git a/plugins/java8-support/src/main/resources/LICENSE.txt b/plugins/java8-support/src/main/resources/LICENSE.txt deleted file mode 100644 index dd5b3a5..0000000 --- a/plugins/java8-support/src/main/resources/LICENSE.txt +++ /dev/null @@ -1,174 +0,0 @@ - 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. diff --git a/plugins/java8-support/src/main/resources/NOTICE.txt b/plugins/java8-support/src/main/resources/NOTICE.txt deleted file mode 100644 index bfba90c..0000000 --- a/plugins/java8-support/src/main/resources/NOTICE.txt +++ /dev/null @@ -1,5 +0,0 @@ -Apache Struts -Copyright 2000-2011 The Apache Software Foundation - -This product includes software developed by -The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/plugins/java8-support/src/main/resources/struts-plugin.xml b/plugins/java8-support/src/main/resources/struts-plugin.xml deleted file mode 100644 index c765cf8..0000000 --- a/plugins/java8-support/src/main/resources/struts-plugin.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- -/* - * $Id$ - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ ---> - -<!DOCTYPE struts PUBLIC - "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" - "http://struts.apache.org/dtds/struts-2.3.dtd"> - -<struts order="25"> - - <bean type="com.opensymphony.xwork2.util.finder.ClassFinderFactory" class="org.apache.struts2.convention.Java8ClassFinderFactory" scope="singleton"/> - -</struts> diff --git a/plugins/java8-support/src/site/site.xml b/plugins/java8-support/src/site/site.xml deleted file mode 100644 index 07a667e..0000000 --- a/plugins/java8-support/src/site/site.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!-- -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ ---> -<project name="Struts 2"> - <skin> - <groupId>org.apache.maven.skins</groupId> - <artifactId>maven-fluido-skin</artifactId> - <version>1.3.1</version> - </skin> - <bannerLeft> - <name>Apache Software Foundation</name> - <src>http://www.apache.org/images/asf-logo.gif</src> - <href>http://www.apache.org/</href> - </bannerLeft> - <bannerRight> - <name>Apache Struts</name> - <src>http://struts.apache.org/img/struts-logo.svg</src> - <href>http://struts.apache.org/</href> - </bannerRight> - <publishDate position="none"/> - <version position="none"/> - <body> - <links> - <item name="Apache" href="http://www.apache.org/"/> - <item name="Struts" href="http://struts.apache.org/"/> - </links> - - <menu ref="parent"/> - <menu ref="reports"/> - - <footer> - <div class="row span12"> - Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts - project logos are trademarks of The Apache Software Foundation. - </div> - </footer> - - </body> -</project> diff --git a/plugins/pom.xml b/plugins/pom.xml index cb8e01b..eb4c5ae 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -43,7 +43,6 @@ <module>embeddedjsp</module> <module>gxp</module> <module>jasperreports</module> - <module>java8-support</module> <module>javatemplates</module> <module>jfreechart</module> <module>jsf</module> diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/DefaultClassFinder.java b/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/DefaultClassFinder.java deleted file mode 100644 index a80849b..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/util/finder/DefaultClassFinder.java +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Copyright 2002-2003,2009 The Apache Software Foundation. - * - * 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 com.opensymphony.xwork2.util.finder; - -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.FileManager; -import com.opensymphony.xwork2.FileManagerFactory; -import com.opensymphony.xwork2.XWorkException; -import com.opensymphony.xwork2.util.logging.Logger; -import com.opensymphony.xwork2.util.logging.LoggerFactory; -import org.apache.commons.lang3.StringUtils; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.commons.EmptyVisitor; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.JarURLConnection; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; - -public class DefaultClassFinder implements ClassFinder { - private static final Logger LOG = LoggerFactory.getLogger(DefaultClassFinder.class); - - private final Map<String, List<Info>> annotated = new HashMap<String, List<Info>>(); - private final Map<String, ClassInfo> classInfos = new LinkedHashMap<String, ClassInfo>(); - - private final List<String> classesNotLoaded = new ArrayList<String>(); - - private boolean extractBaseInterfaces; - private ClassLoaderInterface classLoaderInterface; - private FileManager fileManager; - - public DefaultClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) { - this.classLoaderInterface = classLoaderInterface; - this.extractBaseInterfaces = extractBaseInterfaces; - this.fileManager = ActionContext.getContext().getInstance(FileManagerFactory.class).getFileManager(); - - List<String> classNames = new ArrayList<String>(); - for (URL location : urls) { - try { - if (protocols.contains(location.getProtocol())) { - classNames.addAll(jar(location)); - } else if ("file".equals(location.getProtocol())) { - try { - // See if it's actually a jar - URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/"); - JarURLConnection juc = (JarURLConnection) jarUrl.openConnection(); - juc.getJarFile(); - classNames.addAll(jar(jarUrl)); - } catch (IOException e) { - classNames.addAll(file(location)); - } - } - } catch (Exception e) { - if (LOG.isErrorEnabled()) - LOG.error("Unable to read URL [#0]", e, location.toExternalForm()); - } - } - - for (String className : classNames) { - try { - if (classNameFilter.test(className)) - readClassDef(className); - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Unable to read class [#0]", e, className); - } - } - } - - public DefaultClassFinder(Class... classes){ - this(Arrays.asList(classes)); - } - - public DefaultClassFinder(List<Class> classes){ - this.classLoaderInterface = null; - List<Info> infos = new ArrayList<Info>(); - List<Package> packages = new ArrayList<Package>(); - for (Class clazz : classes) { - - Package aPackage = clazz.getPackage(); - if (aPackage != null && !packages.contains(aPackage)){ - infos.add(new PackageInfo(aPackage)); - packages.add(aPackage); - } - - ClassInfo classInfo = new ClassInfo(clazz, this); - infos.add(classInfo); - classInfos.put(classInfo.getName(), classInfo); - for (Method method : clazz.getDeclaredMethods()) { - infos.add(new MethodInfo(classInfo, method)); - } - - for (Constructor constructor : clazz.getConstructors()) { - infos.add(new MethodInfo(classInfo, constructor)); - } - - for (Field field : clazz.getDeclaredFields()) { - infos.add(new FieldInfo(classInfo, field)); - } - } - - for (Info info : infos) { - for (AnnotationInfo annotation : info.getAnnotations()) { - List<Info> annotationInfos = getAnnotationInfos(annotation.getName()); - annotationInfos.add(info); - } - } - } - - public ClassLoaderInterface getClassLoaderInterface() { - return classLoaderInterface; - } - - public boolean isAnnotationPresent(Class<? extends Annotation> annotation) { - List<Info> infos = annotated.get(annotation.getName()); - return infos != null && !infos.isEmpty(); - } - - public List<String> getClassesNotLoaded() { - return Collections.unmodifiableList(classesNotLoaded); - } - - public List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation) { - classesNotLoaded.clear(); - List<Package> packages = new ArrayList<Package>(); - List<Info> infos = getAnnotationInfos(annotation.getName()); - for (Info info : infos) { - if (info instanceof PackageInfo) { - PackageInfo packageInfo = (PackageInfo) info; - try { - Package pkg = packageInfo.get(); - // double check via proper reflection - if (pkg.isAnnotationPresent(annotation)) { - packages.add(pkg); - } - } catch (ClassNotFoundException e) { - classesNotLoaded.add(packageInfo.getName()); - } - } - } - return packages; - } - - public List<Class> findAnnotatedClasses(Class<? extends Annotation> annotation) { - classesNotLoaded.clear(); - List<Class> classes = new ArrayList<Class>(); - List<Info> infos = getAnnotationInfos(annotation.getName()); - for (Info info : infos) { - if (info instanceof ClassInfo) { - ClassInfo classInfo = (ClassInfo) info; - try { - Class clazz = classInfo.get(); - // double check via proper reflection - if (clazz.isAnnotationPresent(annotation)) { - classes.add(clazz); - } - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - } - return classes; - } - - public List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation) { - classesNotLoaded.clear(); - List<ClassInfo> seen = new ArrayList<ClassInfo>(); - List<Method> methods = new ArrayList<Method>(); - List<Info> infos = getAnnotationInfos(annotation.getName()); - for (Info info : infos) { - if (info instanceof MethodInfo && !"<init>".equals(info.getName())) { - MethodInfo methodInfo = (MethodInfo) info; - ClassInfo classInfo = methodInfo.getDeclaringClass(); - - if (seen.contains(classInfo)) continue; - - seen.add(classInfo); - - try { - Class clazz = classInfo.get(); - for (Method method : clazz.getDeclaredMethods()) { - if (method.isAnnotationPresent(annotation)) { - methods.add(method); - } - } - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - } - return methods; - } - - public List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation) { - classesNotLoaded.clear(); - List<ClassInfo> seen = new ArrayList<ClassInfo>(); - List<Constructor> constructors = new ArrayList<Constructor>(); - List<Info> infos = getAnnotationInfos(annotation.getName()); - for (Info info : infos) { - if (info instanceof MethodInfo && "<init>".equals(info.getName())) { - MethodInfo methodInfo = (MethodInfo) info; - ClassInfo classInfo = methodInfo.getDeclaringClass(); - - if (seen.contains(classInfo)) continue; - - seen.add(classInfo); - - try { - Class clazz = classInfo.get(); - for (Constructor constructor : clazz.getConstructors()) { - if (constructor.isAnnotationPresent(annotation)) { - constructors.add(constructor); - } - } - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - } - return constructors; - } - - public List<Field> findAnnotatedFields(Class<? extends Annotation> annotation) { - classesNotLoaded.clear(); - List<ClassInfo> seen = new ArrayList<ClassInfo>(); - List<Field> fields = new ArrayList<Field>(); - List<Info> infos = getAnnotationInfos(annotation.getName()); - for (Info info : infos) { - if (info instanceof FieldInfo) { - FieldInfo fieldInfo = (FieldInfo) info; - ClassInfo classInfo = fieldInfo.getDeclaringClass(); - - if (seen.contains(classInfo)) continue; - - seen.add(classInfo); - - try { - Class clazz = classInfo.get(); - for (Field field : clazz.getDeclaredFields()) { - if (field.isAnnotationPresent(annotation)) { - fields.add(field); - } - } - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - } - return fields; - } - - public List<Class> findClassesInPackage(String packageName, boolean recursive) { - classesNotLoaded.clear(); - List<Class> classes = new ArrayList<Class>(); - for (ClassInfo classInfo : classInfos.values()) { - try { - if (recursive && classInfo.getPackageName().startsWith(packageName)){ - classes.add(classInfo.get()); - } else if (classInfo.getPackageName().equals(packageName)){ - classes.add(classInfo.get()); - } - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - return classes; - } - - public List<Class> findClasses(Test<ClassInfo> test) { - classesNotLoaded.clear(); - List<Class> classes = new ArrayList<Class>(); - for (ClassInfo classInfo : classInfos.values()) { - try { - if (test.test(classInfo)) { - classes.add(classInfo.get()); - } - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - return classes; - } - - public List<Class> findClasses() { - classesNotLoaded.clear(); - List<Class> classes = new ArrayList<Class>(); - for (ClassInfo classInfo : classInfos.values()) { - try { - classes.add(classInfo.get()); - } catch (Throwable e) { - if (LOG.isErrorEnabled()) - LOG.error("Error loading class [#0]", e, classInfo.getName()); - classesNotLoaded.add(classInfo.getName()); - } - } - return classes; - } - - private static List<URL> getURLs(ClassLoaderInterface classLoader, String[] dirNames) { - List<URL> urls = new ArrayList<URL>(); - for (String dirName : dirNames) { - try { - Enumeration<URL> classLoaderURLs = classLoader.getResources(dirName); - while (classLoaderURLs.hasMoreElements()) { - URL url = classLoaderURLs.nextElement(); - urls.add(url); - } - } catch (IOException ioe) { - if (LOG.isErrorEnabled()) - LOG.error("Could not read driectory [#0]", ioe, dirName); - } - } - - return urls; - } - - private List<String> file(URL location) { - List<String> classNames = new ArrayList<String>(); - File dir = new File(URLDecoder.decode(location.getPath())); - if ("META-INF".equals(dir.getName())) { - dir = dir.getParentFile(); // Scrape "META-INF" off - } - if (dir.isDirectory()) { - scanDir(dir, classNames, ""); - } - return classNames; - } - - private void scanDir(File dir, List<String> classNames, String packageName) { - File[] files = dir.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - scanDir(file, classNames, packageName + file.getName() + "."); - } else if (file.getName().endsWith(".class")) { - String name = file.getName(); - name = name.replaceFirst(".class$", ""); - // Classes packaged in an exploded .war (e.g. in a VFS file system) should not - // have WEB-INF.classes in their package name. - classNames.add(StringUtils.removeStart(packageName, "WEB-INF.classes.") + name); - } - } - } - - private List<String> jar(URL location) throws IOException { - URL url = fileManager.normalizeToFileProtocol(location); - if (url != null) { - InputStream in = url.openStream(); - try { - JarInputStream jarStream = new JarInputStream(in); - return jar(jarStream); - } finally { - in.close(); - } - } else if (LOG.isDebugEnabled()) - LOG.debug("Unable to read [#0]", location.toExternalForm()); - - return Collections.emptyList(); - } - - private List<String> jar(JarInputStream jarStream) throws IOException { - List<String> classNames = new ArrayList<String>(); - - JarEntry entry; - while ((entry = jarStream.getNextJarEntry()) != null) { - if (entry.isDirectory() || !entry.getName().endsWith(".class")) { - continue; - } - String className = entry.getName(); - className = className.replaceFirst(".class$", ""); - - //war files are treated as .jar files, so takeout WEB-INF/classes - className = StringUtils.removeStart(className, "WEB-INF/classes/"); - - className = className.replace('/', '.'); - classNames.add(className); - } - - return classNames; - } - - public class PackageInfo extends Annotatable implements Info { - private final String name; - private final ClassInfo info; - private final Package pkg; - - public PackageInfo(Package pkg){ - super(pkg); - this.pkg = pkg; - this.name = pkg.getName(); - this.info = null; - } - - public PackageInfo(String name, ClassFinder classFinder) { - info = new ClassInfo(name, null, classFinder); - this.name = name; - this.pkg = null; - } - - public String getName() { - return name; - } - - public Package get() throws ClassNotFoundException { - return (pkg != null)?pkg:info.get().getPackage(); - } - } - - private List<Info> getAnnotationInfos(String name) { - List<Info> infos = annotated.get(name); - if (infos == null) { - infos = new ArrayList<Info>(); - annotated.put(name, infos); - } - return infos; - } - - private void readClassDef(String className) { - if (!className.endsWith(".class")) { - className = className.replace('.', '/') + ".class"; - } - try { - URL resource = classLoaderInterface.getResource(className); - if (resource != null) { - InputStream in = resource.openStream(); - try { - ClassReader classReader = new ClassReader(in); - classReader.accept(new InfoBuildingVisitor(this), ClassReader.SKIP_DEBUG); - } finally { - in.close(); - } - } else { - throw new XWorkException("Could not load " + className); - } - } catch (IOException e) { - throw new XWorkException("Could not load " + className, e); - } - - } - - public class InfoBuildingVisitor extends EmptyVisitor { - private Info info; - private ClassFinder classFinder; - - public InfoBuildingVisitor(ClassFinder classFinder) { - this.classFinder = classFinder; - } - - public InfoBuildingVisitor(Info info, ClassFinder classFinder) { - this.info = info; - this.classFinder = classFinder; - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - if (name.endsWith("package-info")) { - info = new PackageInfo(javaName(name), classFinder); - } else { - ClassInfo classInfo = new ClassInfo(javaName(name), javaName(superName), classFinder); - - for (String interfce : interfaces) { - classInfo.getInterfaces().add(javaName(interfce)); - } - info = classInfo; - classInfos.put(classInfo.getName(), classInfo); - - if (extractBaseInterfaces) - extractSuperInterfaces(classInfo); - } - } - - private void extractSuperInterfaces(ClassInfo classInfo) { - String superType = classInfo.getSuperType(); - - if (superType != null) { - ClassInfo base = classInfos.get(superType); - - if (base == null) { - //try to load base - String resource = superType.replace('.', '/') + ".class"; - readClassDef(resource); - base = classInfos.get(superType); - } - - if (base != null) { - List<String> interfaces = classInfo.getSuperInterfaces(); - interfaces.addAll(base.getSuperInterfaces()); - interfaces.addAll(base.getInterfaces()); - } - } - } - - private String javaName(String name) { - return (name == null)? null:name.replace('/', '.'); - } - - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - AnnotationInfo annotationInfo = new AnnotationInfo(desc); - info.getAnnotations().add(annotationInfo); - getAnnotationInfos(annotationInfo.getName()).add(info); - return new InfoBuildingVisitor(annotationInfo, classFinder); - } - - @Override - public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { - ClassInfo classInfo = ((ClassInfo) info); - FieldInfo fieldInfo = new FieldInfo(classInfo, name, desc); - classInfo.getFields().add(fieldInfo); - return new InfoBuildingVisitor(fieldInfo, classFinder); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - ClassInfo classInfo = ((ClassInfo) info); - MethodInfo methodInfo = new MethodInfo(classInfo, name, desc); - classInfo.getMethods().add(methodInfo); - return new InfoBuildingVisitor(methodInfo, classFinder); - } - - @Override - public AnnotationVisitor visitParameterAnnotation(int param, String desc, boolean visible) { - MethodInfo methodInfo = ((MethodInfo) info); - List<AnnotationInfo> annotationInfos = methodInfo.getParameterAnnotations(param); - AnnotationInfo annotationInfo = new AnnotationInfo(desc); - annotationInfos.add(annotationInfo); - return new InfoBuildingVisitor(annotationInfo, classFinder); - } - } - - private static final class DefaultClassnameFilterImpl implements Test<String> { - public boolean test(String className) { - return true; - } - } -} - -- To stop receiving notification emails like this one, please contact lukaszlen...@apache.org.