Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wicketstuff.rest.utils.mounting; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.request.resource.IResource; import org.apache.wicket.request.resource.ResourceReference; import org.apache.wicket.util.lang.Args; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.wicketstuff.rest.annotations.ResourcePath; public class PackageScanner { private static final Logger log = LoggerFactory.getLogger(PackageScanner.class); public static void scanPackage(String... packageNames) { Args.notNull(packageNames, "packageNames"); scanPackage(WebApplication.get(), packageNames); } public static void scanPackage(WebApplication application, String... packageNames) { Args.notNull(application, "application"); Args.notNull(packageNames, "packageNames"); for (String packageName : packageNames) { scanPackage(application, packageName); } } public static void scanPackage(WebApplication application, String packageName) { Args.notNull(application, "application"); Args.notNull(packageName, "packageName"); try { Class<?>[] packageClasses = getClasses(packageName); for (Class<?> clazz : packageClasses) { mountAnnotatedResource(application, clazz); } } catch (Exception exception) { throw new WicketRuntimeException(exception); } } private static void mountAnnotatedResource(WebApplication application, Class<?> clazz) throws InstantiationException, IllegalAccessException { ResourcePath mountAnnotation = clazz.getAnnotation(ResourcePath.class); if (mountAnnotation == null || !IResource.class.isAssignableFrom(clazz)) { return; } String path = mountAnnotation.value(); final IResource resourceInstance = (IResource) clazz.newInstance(); application.mountResource(path, new ResourceReference(clazz.getSimpleName()) { /** * */ private static final long serialVersionUID = 1L; @Override public IResource getResource() { return resourceInstance; } }); log.info("Resource '" + clazz.getSimpleName() + "' has been mounted to path '" + path + "'"); } /** * Scans all classes accessible from the context class loader which belong * to the given package and subpackages. * * Credits: http://www.dzone.com/snippets/get-all-classes-within-package * * @param packageName * The base package * @return The classes * @throws ClassNotFoundException * @throws IOException */ private static Class<?>[] getClasses(String packageName) throws ClassNotFoundException, IOException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Args.notNull(classLoader, "classLoader"); String path = packageName.replace('.', '/'); Enumeration<URL> resources = classLoader.getResources(path); List<File> dirs = new ArrayList<File>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(new File(resource.getFile())); } ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); for (File directory : dirs) { classes.addAll(findClasses(directory, packageName)); } return classes.toArray(new Class[classes.size()]); } /** * Recursive method used to find all classes in a given directory and * subdirs. * * Credits: http://www.dzone.com/snippets/get-all-classes-within-package * * @param directory * The base directory * @param packageName * The package name for classes found inside the base directory * @return The classes * @throws ClassNotFoundException */ private static List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException { List<Class<?>> classes = new ArrayList<Class<?>>(); if (!directory.exists()) { return classes; } File[] files = directory.listFiles(); for (File file : files) { if (file.isDirectory()) { classes.addAll(findClasses(file, packageName + "." + file.getName())); } else if (file.getName().endsWith(".class")) { classes.add(Class .forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6))); } } return classes; } }