All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.admin.rest.generator.CommandResourceMetaData Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package org.glassfish.admin.rest.generator;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.glassfish.api.admin.AdminCommand;
import org.glassfish.api.admin.RestEndpoint;
import org.glassfish.api.admin.RestEndpoints;
import org.glassfish.api.admin.RestParam;
import org.glassfish.config.support.Create;
import org.glassfish.config.support.Delete;
import org.glassfish.hk2.api.ActiveDescriptor;
import org.glassfish.hk2.api.MultiException;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.BuilderHelper;
import org.glassfish.internal.api.Globals;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.ConfigBeanProxy;
import org.jvnet.hk2.config.ConfigInjector;

/**
 * @author Mitesh Meswani
 */
public class CommandResourceMetaData {

    public String command;
    public String httpMethod;
    public String resourcePath;
    public String displayName;
    public ParameterMetaData[] commandParams;
    public String customClassName; // used by the custom resource mapping
    private static final Map> restRedirects = new HashMap>();

    public static class ParameterMetaData {
        String name;
        String value;
    }

    public static List getMetaData(String beanName) {
        //TODO need to read this from a file instead of from memory and then initialize data structure Map >
        List retVal = new LinkedList();
        for (String[] currentRow : configBeansToCommandResourcesMap) {
            if (beanName.equals(currentRow[0])) {
                CommandResourceMetaData metaData = new CommandResourceMetaData();
                metaData.command = currentRow[1];
                metaData.httpMethod = currentRow[2];
                metaData.resourcePath = currentRow[3];
                metaData.displayName = currentRow[4];
                // Each row has variable no of commandParams. If commandParams are present, extract them from current row and stuff into a String[]
                int PARAMETER_START_INDEX = 5;
                if (currentRow.length > PARAMETER_START_INDEX) {
                    metaData.commandParams = new ParameterMetaData[currentRow.length - PARAMETER_START_INDEX];
                    for (int i = PARAMETER_START_INDEX; i < currentRow.length; i++) {
                        String[] nameValue = currentRow[i].split("=", 2); // The params are written as 'name=value', split them around "="
                        ParameterMetaData currentParam = new ParameterMetaData();
                        metaData.commandParams[i - PARAMETER_START_INDEX] = currentParam;
                        currentParam.name = nameValue[0];
                        currentParam.value = nameValue[1];
                    }
                }
                retVal.add(metaData);
            }
        }
        final List restRedirectPointToBean = getRestRedirectPointToBean(beanName);
        if (restRedirectPointToBean != null) {
            retVal.addAll(restRedirectPointToBean);
        }
        return retVal;
    }

    public static List getCustomResourceMapping(String beanName) {
        List customResources = new LinkedList();
        for (String[] row : configBeanCustomResources) {
            if (row[0].equals(beanName)) {
                CommandResourceMetaData metaData = new CommandResourceMetaData();
                metaData.customClassName = row[1];
                metaData.resourcePath = row[2];

                customResources.add(metaData);
            }
        }

        return customResources;
    }

    @SuppressWarnings("unchecked")
    public static List getRestRedirectPointToBean(String beanName) {
        synchronized (restRedirects) {
            if (restRedirects.isEmpty()) {
                final ServiceLocator habitat = Globals.getDefaultHabitat();

                processConfigBeans(habitat);

                List> iter = habitat.getDescriptors(
                        BuilderHelper.createContractFilter(AdminCommand.class.getName()));
                for (ActiveDescriptor ad : iter) {
                    if (!(ad.getQualifiers().contains(RestEndpoints.class.getName()))) {
                        continue;
                    }
                    
                    if (!ad.isReified()) {
                        try {
                            habitat.reifyDescriptor(ad);
                        }
                        catch (MultiException me) {
                            // If we can't see the command, forget it
                            continue;
                        }
                    }
                    
                    final Class clazz = (Class) ad.getImplementationClass();
                    RestEndpoints endpoints = clazz.getAnnotation(RestEndpoints.class);
                    if (endpoints != null) {
                        RestEndpoint[] list = endpoints.value();
                        if ((list != null) && (list.length > 0)) {
                            for (RestEndpoint endpoint : list) {
                                Service service = clazz.getAnnotation(Service.class);
                                String configBean = endpoint.configBean().getSimpleName();

                                CommandResourceMetaData metaData = new CommandResourceMetaData();
                                metaData.command = service.name();
                                metaData.httpMethod = endpoint.opType().name();
                                metaData.resourcePath = endpoint.path().isEmpty() ? service.name() : endpoint.path();
                                metaData.displayName = endpoint.description().isEmpty() ? metaData.resourcePath : endpoint.description();

                                metaData.commandParams = new ParameterMetaData[endpoint.params().length];
                                int index = 0;
                                for (RestParam param : endpoint.params()) {
                                    ParameterMetaData currentParam = new ParameterMetaData();
                                    metaData.commandParams[index] = currentParam;
                                    currentParam.name = param.name();
                                    currentParam.value = param.value();
                                    index++;
                                }
                                addCommandMetaData(configBean, metaData);
                            }
                        }
                    }
                }
            }
        }

        return restRedirects.get(beanName);
    }

    private static void processConfigBeans(ServiceLocator serviceLocator) {

		List> allDescriptors = serviceLocator.getDescriptors(
		        BuilderHelper.createContractFilter(ConfigInjector.class.getName()));
		
		HashSet alreadyChecked = new HashSet();

        for (ActiveDescriptor ad : allDescriptors){
            List targets = ad.getMetadata().get("target");
            if (targets == null) continue;
            
            for (String t : targets) {
                if (alreadyChecked.contains(t)) continue;
                alreadyChecked.add(t);
                
                try {
                    Class tclass = Class.forName(t);
                    if (tclass != null && ConfigBeanProxy.class.isAssignableFrom(tclass)) {
                        String beanName = tclass.getSimpleName();
                        for (Method m : tclass.getMethods()) {
                            if (m.isAnnotationPresent(Create.class)) {
                                addCreateMethod(beanName, m, m.getAnnotation(Create.class));
                            } else if (m.isAnnotationPresent(Delete.class)) {
                                addDeleteMethod(beanName, m, m.getAnnotation(Delete.class));
                            }
                        }
                    }
                } catch (ClassNotFoundException cnfe) {
                    continue;
                }
            }
        }
    }

    private static void addCreateMethod(String beanName, Method m, Create create) {
        CommandResourceMetaData metaData = new CommandResourceMetaData();
        metaData.command = create.value();
        metaData.httpMethod = "POST";
        metaData.resourcePath = create.value();
        metaData.displayName = create.value();
        addCommandMetaData(beanName, metaData);
    }

    private static void addDeleteMethod(String beanName, Method m, Delete delete) {
        CommandResourceMetaData metaData = new CommandResourceMetaData();
        metaData.command = delete.value();
        metaData.httpMethod = "DELETE";
        metaData.resourcePath = delete.value();
        metaData.displayName = delete.value();
        addCommandMetaData(beanName, metaData);
    }

    private static void addCommandMetaData(String beanName, CommandResourceMetaData cmd) {
        List commandList = restRedirects.get(beanName);
        if (commandList == null) {
            commandList = new ArrayList();
            restRedirects.put(beanName, commandList);
        }
        commandList.add(cmd);
    }

    // This data structure is for exceptional cases only. The preferred mapping approach is to
    // use @RestEndpoints/@RestEndpoint
    private static String configBeansToCommandResourcesMap[][] = {
        //{config-bean, command, method, resource-path, command-action, command-params...}
        {"Domain", "change-admin-password", "POST", "change-admin-password", "change-admin-password"},
        {"Domain", "stop-domain", "POST", "stop", "Stop"},
        {"IiopListener", "create-ssl", "POST", "create-ssl", "Create", "id=$parent", "type=iiop-listener"}, // Not used? IiopListener not in nucleus
        {"IiopService", "create-ssl", "POST", "create-ssl", "Create", "type=iiop-service"}, // Not used? IiopListener not in nucleus
        {"LbConfig", "create-http-listener", "POST", "create-http-listener", "create-http-listener"},
        {"LbConfig", "delete-http-listener", "POST", "delete-http-listener", "delete-http-listener"},
        {"ListApplication", "create-lifecycle-module", "POST", "create-lifecycle-module", "Create Lifecycle Module"}, // TODO: ListApplication not found
        {"ListApplication", "delete-lifecycle-module", "DELETE", "delete-lifecycle-module", "Delete Lifecycle Module"},};
    private static final String[][] configBeanCustomResources = {
        // ConfigBean, Custom Resource Class, path
        {"Cluster", "SystemPropertiesCliResource", "system-properties"},
        {"Config", "SystemPropertiesCliResource", "system-properties"},
        {"Domain", "JmxServiceUrlsResource", "jmx-urls"},
        {"Domain", "LogViewerResource", "view-log"},
        {"Domain", "NotificationLogViewer", "notification-log-view"},
        {"Domain", "SetDomainConfigResource", "set"},
        {"Domain", "SystemPropertiesCliResource", "system-properties"},
        {"NetworkListener", "FindHttpProtocolResource", "find-http-protocol"},
        {"Server", "SystemPropertiesCliResource", "system-properties"}
    };
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy