org.makersoft.mvc.builder.PackageBasedUrlPathBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.makersoft.mvc.builder.PackageBasedUrlPathBuilder.java

Source

/*
 * @(#)PackageBasedUrlPathBuilder.java 2013-1-31 ?23:33:33
 *
 * Copyright (c) 2011-2013 Makersoft.org all rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 */
package org.makersoft.mvc.builder;

import java.lang.reflect.Modifier;

import org.apache.commons.lang3.StringUtils;
import org.makersoft.log.Log;
import org.makersoft.log.LoggerFactory;

/**
 * Class description goes here.
 */
public class PackageBasedUrlPathBuilder {

    private static final Log LOG = LoggerFactory.getLogger(PackageBasedUrlPathBuilder.class);

    /**
     *  "web", "controller", "action", "controllers"
     */
    private final String[] packageLocators;

    /**
     *  "org.makersoft.web.mvc.controllers"
     */
    private final String[] controllerPackages;

    /**
     * root path
     */
    private final String root;

    private final ControllerNameBuilder builder;

    /**
     * 
     * @param packageLocators
     * @param controllerPackages
     * @param controllerSuffix
     * @param root
     */
    public PackageBasedUrlPathBuilder(String[] packageLocators, String[] controllerPackages,
            String controllerSuffix, String root) {

        this.packageLocators = packageLocators;
        this.controllerPackages = controllerPackages;
        this.root = StringUtils.isBlank(root) ? "application#index" : root;
        this.builder = new SEOControllerNameBuilder(controllerSuffix);
    }

    /**
     * ?Controller?URL
     * 
     * @param clazz
     *            Controller
     * @return URL Path
     */
    public String[] buildUrlPath(Class<?> controllerClass, String methodName, String... values) {

        // Skip classes that can't be instantiated
        if (cannotInstantiate(controllerClass)) {
            if (LOG.isTraceEnabled())
                LOG.trace("Class [#0] did not pass the instantiation test and will be ignored",
                        controllerClass.getName());
        }

        // Determine the action package
        String controllerPackage = controllerClass.getPackage().getName();
        if (LOG.isDebugEnabled()) {
            LOG.debug("Processing class [#0] in package [#1]", controllerClass.getName(), controllerPackage);
        }

        // Determine the default namespace and action name
        String namespace = determineControllerNamespace(controllerClass);

        String defaultControllerName = determineControllerName(controllerClass);

        // reversion
        String[] urlPaths = null;

        // fixed root path
        if (root.equals(defaultControllerName + "#" + methodName)) {
            urlPaths = new String[] { "/" };
        } else if (values.length != 0) {
            urlPaths = new String[values.length];
            for (int i = 0; i < values.length; i++) {
                String value = values[i];
                urlPaths[i] = namespace + "/" + defaultControllerName + value;
            }
        } else {
            urlPaths = new String[] { namespace + "/" + defaultControllerName };
        }

        return urlPaths;
    }

    /**
     * Determines the namespace(s) for the action based on the action class. If there is a {
     * Namespace} annotation on the class (including parent classes) or on the package that the
     * class is in, than it is used. Otherwise, the Java package name that the class is in is used
     * in conjunction with either the <b>struts.convention.action.packages</b> or
     * <b>struts.convention.package.locators</b> configuration values. These are used to determine
     * which part of the Java package name should be converted into the namespace for the XWork
     * PackageConfig.
     * 
     * @param actionClass
     *            The action class.
     * @return The namespace or an empty string.
     */
    private String determineControllerNamespace(Class<?> controllerClass) {
        String urlPath;

        String pkg = controllerClass.getPackage().getName();
        String pkgPart = null;
        if (controllerPackages != null) {
            for (String actionPackage : controllerPackages) {
                if (pkg.startsWith(actionPackage)) {
                    pkgPart = controllerClass.getName().substring(actionPackage.length() + 1);
                }
            }
        }

        if (pkgPart == null && packageLocators != null) {
            for (String packageLocator : packageLocators) {
                int index = pkg.lastIndexOf(packageLocator);

                // This ensures that the match is at the end, beginning or has a dot on each side of it
                if (index >= 0 && (index + packageLocator.length() == pkg.length() || index == 0
                        || (pkg.charAt(index - 1) == '.' && pkg.charAt(index + packageLocator.length()) == '.'))) {
                    pkgPart = controllerClass.getName().substring(index + packageLocator.length() + 1);
                }
            }
        }

        if (pkgPart != null) {
            final int indexOfDot = pkgPart.lastIndexOf('.');
            if (indexOfDot >= 0) {
                // String convertedNamespace = this.build(pkgPart.substring(0, indexOfDot));
                String convertedNamespace = pkgPart.substring(0, indexOfDot);
                urlPath = "/" + convertedNamespace.replace('.', '/');
                return urlPath;
            }
        }

        return "";
    }

    /**
     * Converts the class name into an action name using the ActionNameBuilder.
     * 
     * @param actionClass
     *            The action class.
     * @return The action name.
     */
    protected String determineControllerName(Class<?> controllerClass) {

        String controllerName = builder.build(controllerClass.getSimpleName());
        if (LOG.isTraceEnabled()) {
            LOG.trace("Got actionName for class [#0] of [#1]", controllerClass.toString(), controllerName);
        }

        return controllerName;
    }

    public static String urlPathConvert(Class<?> clazz, String[] packageLocators, String... values) {
        return null;
    }

    /**
     * Interfaces, enums, annotations, and abstract classes cannot be instantiated.
     * 
     * @param controllerClass
     *            class to check
     * @return returns true if the class cannot be instantiated or should be ignored
     */
    protected boolean cannotInstantiate(Class<?> controllerClass) {
        return controllerClass.isAnnotation() || controllerClass.isInterface() || controllerClass.isEnum()
                || (controllerClass.getModifiers() & Modifier.ABSTRACT) != 0 || controllerClass.isAnonymousClass();
    }

}