org.echocat.nodoodle.server.BaseUrlsDiscovery.java Source code

Java tutorial

Introduction

Here is the source code for org.echocat.nodoodle.server.BaseUrlsDiscovery.java

Source

/*****************************************************************************************
 * *** BEGIN LICENSE BLOCK *****
 *
 * Version: MPL 2.0
 *
 * echocat NoDoodle, Copyright (c) 2010-2012 echocat
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * *** END LICENSE BLOCK *****
 ****************************************************************************************/

package org.echocat.nodoodle.server;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.echocat.nodoodle.IllegalBaseUrlException;

import javax.servlet.ServletContext;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import static org.apache.commons.lang.StringUtils.isEmpty;

public class BaseUrlsDiscovery {

    public static interface DoOnMatchingBaseUrl<T> {
        public T execute(String id, URL matchingBaseUrl);
    }

    private Collection<URL> _baseUrls;
    private ServletContext _servletContext;

    public void init(ServletContext servletContext) throws Exception {
        if (servletContext == null) {
            throw new NullPointerException("No servletContext provided.");
        }
        if (CollectionUtils.isEmpty(_baseUrls)) {
            throw new IllegalArgumentException("No baseUrls property set.");
        }
        for (URL baseUrl : _baseUrls) {
            if (!StringUtils.isEmpty(baseUrl.getQuery())) {
                throw new IllegalArgumentException("The given baseUrl (" + baseUrl + ") does contain a query.");
            }
        }
        _servletContext = servletContext;
    }

    public void destroy() throws Exception {
        _servletContext = null;
    }

    public void setBaseUrls(Collection<URL> baseUrls) {
        _baseUrls = baseUrls;
    }

    public boolean isAvailable(URL url) {
        if (url == null) {
            throw new NullPointerException("The url is not defined.");
        }
        final ServletContext servletContext = _servletContext;
        if (servletContext == null) {
            throw new IllegalStateException("The init() method was not yet called.");
        }
        if (CollectionUtils.isEmpty(_baseUrls)) {
            throw new IllegalArgumentException("No baseUrls property set.");
        }
        boolean baseUrlFound = false;
        final Iterator<URL> i = _baseUrls.iterator();
        while (i.hasNext() && !baseUrlFound) {
            final URL baseUrl = i.next();
            baseUrlFound = url.toExternalForm().startsWith(baseUrl.toExternalForm());
        }
        final boolean result;
        if (baseUrlFound) {
            final String uriPath = url.getPath();
            final ServletContext servletContextForUrl = servletContext.getContext(uriPath);
            result = servletContext.equals(servletContextForUrl);
        } else {
            result = false;
        }
        return result;
    }

    public List<URL> createBaseUrlsFor(String id, URL preferredBaseUrl) {
        final List<URL> baseUrls = new ArrayList<URL>();
        for (URL baseUrl : _baseUrls) {
            final URL baseUrlForId;
            try {
                baseUrlForId = new URL(baseUrl + id);
            } catch (MalformedURLException e) {
                throw new RuntimeException("Could not build the new url from " + baseUrl + " and " + id + ".", e);
            }
            if (!isAvailable(baseUrlForId)) {
                if (baseUrlForId.equals(preferredBaseUrl)) {
                    throw new IllegalBaseUrlException(
                            "The preferredBaseUrl '" + preferredBaseUrl + "' is not available.");
                }
            } else if (baseUrlForId.equals(preferredBaseUrl)) {
                baseUrls.add(0, baseUrlForId);
            } else {
                baseUrls.add(baseUrlForId);
            }
        }
        return baseUrls;
    }

    public String selectIdFrom(URL url) throws IllegalBaseUrlException {
        if (url == null) {
            throw new NullPointerException("No preferredBaseUrl given.");
        }
        if (!isEmpty(url.getQuery())) {
            throw new IllegalBaseUrlException("The given preferredBaseUrl (" + url + ") contains a query.");
        }
        final Iterator<URL> i = _baseUrls.iterator();
        String result = null;
        while (i.hasNext() && result == null) {
            final URL baseUrl = i.next();
            if (baseUrl.getProtocol().equals(url.getProtocol()) && baseUrl.getHost().equals(url.getHost())
                    && baseUrl.getPort() == url.getPort()) {
                final String plainBaseUrlPath = baseUrl.getPath();
                final String baseUrlPath = plainBaseUrlPath
                        + (plainBaseUrlPath.endsWith("/") ? "" : plainBaseUrlPath + "/");
                final String preferredBaseUrlPath = url.getPath();
                if (preferredBaseUrlPath.startsWith(baseUrlPath)
                        && preferredBaseUrlPath.length() > baseUrlPath.length()) {
                    final String leftPreferredBasePath = preferredBaseUrlPath.substring(baseUrlPath.length());
                    final int lastSlash = leftPreferredBasePath.indexOf('/');
                    result = lastSlash > 0 ? leftPreferredBasePath.substring(0, lastSlash) : leftPreferredBasePath;
                }
            }
        }
        return result;
    }

}