org.apache.wicket.application.CompoundClassResolver.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.application.CompoundClassResolver.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.application;

import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.wicket.util.collections.UrlExternalFormComparator;
import org.apache.wicket.util.lang.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A thread safe compound {@link IClassResolver}. Class resolving is done by iterating through all
 * {@link IClassResolver}s until the class is found. Resource resolving is done by combining the
 * results of all {@link IClassResolver}s.
 * 
 * @author Jesse Long
 */
public class CompoundClassResolver implements IClassResolver {
    private static final Logger logger = LoggerFactory.getLogger(CompoundClassResolver.class);

    private final List<IClassResolver> resolvers = new CopyOnWriteArrayList<IClassResolver>();

    /**
     * {@inheritDoc}
     * <p>
     * This implementation iterates through all the {@link IClassResolver} trying to load the class
     * until the class is found.
     * 
     * @param className
     *            The name of the class to resolve.
     * @return The {@link Class}, if it is found.
     * @throws ClassNotFoundException
     *             If the class was not found
     */
    @Override
    public Class<?> resolveClass(final String className) throws ClassNotFoundException {
        boolean debugEnabled = logger.isDebugEnabled();

        for (IClassResolver resolver : resolvers) {
            try {
                return resolver.resolveClass(className);
            } catch (ClassNotFoundException cnfx) {
                if (debugEnabled) {
                    logger.debug("ClassResolver '{}' cannot find class: '{}'", resolver.getClass().getName(),
                            className);
                }
            }
        }

        throw new ClassNotFoundException(className);
    }

    /**
     * {@inheritDoc}
     * <p>
     * This implementation iterates through all {@link IClassResolver}s added, and combines the
     * results into one {@link Set} of {@link URL}s, and returns an {@link Iterator} for the set.
     * {@link URL}s are unique in the set.
     * 
     * @param name
     *            The name of the resource to find.
     * @return An {@link Iterator} of all the {@link URL}s matching the resource name.
     */
    @Override
    public Iterator<URL> getResources(final String name) {
        Args.notNull(name, "name");

        Set<URL> urls = new TreeSet<URL>(new UrlExternalFormComparator());

        for (IClassResolver resolver : resolvers) {
            Iterator<URL> it = resolver.getResources(name);
            while (it.hasNext()) {
                URL url = it.next();
                urls.add(url);
            }
        }

        return urls.iterator();
    }

    /**
     * @return the class loader returned by the first registered IClassResolver. If there is no
     *  registered IClassResolver then the current thread's context class loader will be returned.
     */
    @Override
    public ClassLoader getClassLoader() {
        final ClassLoader classLoader;
        if (resolvers.isEmpty() == false) {
            classLoader = resolvers.iterator().next().getClassLoader();
        } else {
            classLoader = Thread.currentThread().getContextClassLoader();
        }
        return classLoader;
    }

    /**
     * Adds a resolver
     * 
     * @param resolver
     *            The resolver to add
     * @return {@code this} for chaining
     */
    public CompoundClassResolver add(final IClassResolver resolver) {
        Args.notNull(resolver, "resolver");
        resolvers.add(resolver);
        return this;
    }

    /**
     * Removes a resolver
     * 
     * @param resolver
     *            The resolver to remove
     * @return {@code this} for chaining
     */
    public CompoundClassResolver remove(final IClassResolver resolver) {
        resolvers.remove(resolver);
        return this;
    }
}