diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java index a88fe00e9fe..3db6a31551c 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java @@ -36,11 +36,14 @@ import org.wso2.carbon.apimgt.webapp.publisher.config.PermissionManagementExcept import javax.servlet.ServletContext; import javax.ws.rs.*; +import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; @@ -85,16 +88,13 @@ public class AnnotationProcessor { * @throws IOException */ public Set scanStandardContext(String className) throws IOException { - AnnotationDB db = new AnnotationDB(); + ExtendedAnnotationDB db = new ExtendedAnnotationDB(); db.addIgnoredPackages(PACKAGE_ORG_APACHE); db.addIgnoredPackages(PACKAGE_ORG_CODEHAUS); db.addIgnoredPackages(PACKAGE_ORG_SPRINGFRAMEWORK); - URL[] libPath = WarUrlFinder.findWebInfLibClasspaths(servletContext); - URL classPath = WarUrlFinder.findWebInfClassesPath(servletContext); - URL[] urls = (URL[]) ArrayUtils.add(libPath, libPath.length, classPath); - - db.scanArchives(urls); + URL classPath = findWebInfClassesPath(servletContext); + db.scanArchives(classPath); //Returns a list of classes with given Annotation return db.getAnnotationIndex().get(className); @@ -387,4 +387,28 @@ public class AnnotationProcessor { } } + /** + * Find the URL pointing to "/WEB-INF/classes" This method may not work in conjunction with IteratorFactory + * if your servlet container does not extract the /WEB-INF/classes into a real file-based directory + * + * @param servletContext + * @return null if cannot determin /WEB-INF/classes + */ + public static URL findWebInfClassesPath(ServletContext servletContext) + { + String path = servletContext.getRealPath("/WEB-INF/classes"); + if (path == null) return null; + File fp = new File(path); + if (fp.exists() == false) return null; + try + { + URI uri = fp.toURI(); + return uri.toURL(); + } + catch (MalformedURLException e) + { + throw new RuntimeException(e); + } + } + } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedAnnotationDB.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedAnnotationDB.java new file mode 100644 index 00000000000..24fdd738b87 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedAnnotationDB.java @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* 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.wso2.carbon.apimgt.webapp.publisher.lifecycle.util; + +import org.scannotation.AnnotationDB; +import org.scannotation.archiveiterator.Filter; +import org.scannotation.archiveiterator.StreamIterator; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +public class ExtendedAnnotationDB extends AnnotationDB { + + public ExtendedAnnotationDB() { + super(); + } + + public void scanArchives(URL... urls) throws IOException { + URL[] arr$ = urls; + int len$ = urls.length; + + for(int i$ = 0; i$ < len$; ++i$) { + URL url = arr$[i$]; + Filter filter = new Filter() { + public boolean accepts(String filename) { + if(filename.endsWith(".class")) { + if(filename.startsWith("/") || filename.startsWith("\\")) { + filename = filename.substring(1); + } + + if(!ExtendedAnnotationDB.this.ignoreScan(filename.replace('/', '.'))) { + return true; + } + } + return false; + } + }; + StreamIterator it = ExtendedIteratorFactory.create(url, filter); + + InputStream stream; + while((stream = it.next()) != null) { + this.scanClass(stream); + } + } + + } + + private boolean ignoreScan(String intf) { + String[] arr$; + int len$; + int i$; + String ignored; + if(this.scanPackages != null) { + arr$ = this.scanPackages; + len$ = arr$.length; + + for(i$ = 0; i$ < len$; ++i$) { + ignored = arr$[i$]; + if(intf.startsWith(ignored + ".")) { + return false; + } + } + + return true; + } else { + arr$ = this.ignoredPackages; + len$ = arr$.length; + + for(i$ = 0; i$ < len$; ++i$) { + ignored = arr$[i$]; + if(intf.startsWith(ignored + ".")) { + return true; + } + } + return false; + } + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedFileProtocolIteratorFactory.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedFileProtocolIteratorFactory.java new file mode 100644 index 00000000000..34936f61c8c --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedFileProtocolIteratorFactory.java @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* 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.wso2.carbon.apimgt.webapp.publisher.lifecycle.util; + +import org.scannotation.archiveiterator.*; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +public class ExtendedFileProtocolIteratorFactory implements DirectoryIteratorFactory { + + private static final String ENCODING_SCHEME = "UTF-8"; + + @Override + public StreamIterator create(URL url, Filter filter) throws IOException { + File f = new File(java.net.URLDecoder.decode(url.getPath(), ENCODING_SCHEME)); + return f.isDirectory()?new FileIterator(f, filter):new JarIterator(url.openStream(), filter); + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedIteratorFactory.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedIteratorFactory.java new file mode 100644 index 00000000000..a62a58f7333 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/ExtendedIteratorFactory.java @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* 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.wso2.carbon.apimgt.webapp.publisher.lifecycle.util; + +import org.scannotation.archiveiterator.DirectoryIteratorFactory; +import org.scannotation.archiveiterator.Filter; +import org.scannotation.archiveiterator.JarIterator; +import org.scannotation.archiveiterator.StreamIterator; + +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.ConcurrentHashMap; + +public class ExtendedIteratorFactory { + + private static final ConcurrentHashMap registry = new ConcurrentHashMap(); + + public static StreamIterator create(URL url, Filter filter) throws IOException { + String urlString = url.toString(); + if(urlString.endsWith("!/")) { + urlString = urlString.substring(4); + urlString = urlString.substring(0, urlString.length() - 2); + url = new URL(urlString); + } + + if(!urlString.endsWith("/")) { + return new JarIterator(url.openStream(), filter); + } else { + DirectoryIteratorFactory factory = registry.get(url.getProtocol()); + if(factory == null) { + throw new IOException("Unable to scan directory of protocol: " + url.getProtocol()); + } else { + return factory.create(url, filter); + } + } + } + + static { + registry.put("file", new ExtendedFileProtocolIteratorFactory()); + } +}