Package org.glassfish.admin.rest

Source Code of org.glassfish.admin.rest.GeneratorResource

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2009 Sun Microsystems, Inc. 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.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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;

import com.sun.enterprise.config.serverbeans.Domain;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import javax.ws.rs.Path;

import org.glassfish.api.admin.CommandModel;
import org.glassfish.api.admin.CommandRunner;
import org.jvnet.hk2.config.ConfigModel;
import org.jvnet.hk2.config.Dom;
import org.jvnet.hk2.config.DomDocument;
import org.jvnet.hk2.config.ConfigBeanProxy;
import org.glassfish.api.admin.RestRedirects;
import org.glassfish.api.admin.RestRedirect;

/**
* @author Ludovic Champenois ludo@dev.java.net
* @author Rajeshwar Patil
*/
@Path("/generator/")
public class GeneratorResource {

    private DomDocument document;
    protected String genDir;

    /** Creates a new instance of xxxResource */
    public GeneratorResource() {
    }

    @GET
    @Produces({"text/plain"})
    public String get() {

        Domain entity = RestService.getDomain();

        File loc =
                new File(System.getProperty("user.home") + "/acvs/v3/admin/rest/src/main/java/org/glassfish/admin/rest/resources");
        loc.mkdirs();
        genDir = loc.getAbsolutePath();

        //generate date info in 1 single file
        File file = new File(genDir + "/codegeneration.properties");
        try {
            file.createNewFile();
            FileWriter fstream = new FileWriter(file);
            BufferedWriter out = new BufferedWriter(fstream);
            out.write("generation_date=" + new Date() + "\n");
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }







        //        DomDocument dodo = RestService.getHabitat().getComponent(DomDocument.class);
        //        Dom root = dodo.getRoot();
        // System.out.println(" root "+ root );
        Dom dom1 = Dom.unwrap(entity);
        Dom root = dom1.document.getRoot();
        document = dom1.document;

        ConfigModel rootModel = root.model;


        //+ Domain domain = Domain.class.cast(RestService.getHabitat().getComponent(Domain.class.getName(), ""));
        try {
            generateSingle(rootModel);
        } catch (Exception ex) {
            Logger.getLogger(GeneratorResource.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "Code Generation done at : " + genDir;

    }

    private void processRedirectsAnnotation(ConfigModel model) {

        Class<? extends ConfigBeanProxy> cbp = null;
        System.out.println("\n\nAnnotation" + model.targetTypeName);
        try {
            cbp = (Class<? extends ConfigBeanProxy>) model.classLoaderHolder.get().loadClass(model.targetTypeName);
            // cbp = (Class<? extends ConfigBeanProxy>)this.getClass().getClassLoader().loadClass(model.targetTypeName) ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("re Annotation" + model.targetTypeName);
        RestRedirects restRedirects = cbp.getAnnotation(RestRedirects.class);
        System.out.println("re Annotation restRedirects" + restRedirects);
        if (restRedirects != null) {
            System.out.println("LUDO: NOT NULL                Annotation restRedirects" + restRedirects);

            RestRedirect[] values = restRedirects.value();
            for (RestRedirect r : values) {
                System.out.println(r.commandName());
                System.out.println(r.opType());
            }
        }


    }


    private void genHeader(BufferedWriter out) throws IOException {
        out.write("/*\n");
        out.write(" * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.\n");
        out.write(" *\n");
        out.write(" * Copyright 2009 Sun Microsystems, Inc. All rights reserved.\n");
        out.write(" *\n");
        out.write(" * The contents of this file are subject to the terms of either the GNU\n");
        out.write(" * General Public License Version 2 only (\"GPL\") or the Common Development\n");
        out.write(" * and Distribution License(\"CDDL\") (collectively, the \"License\").  You\n");
        out.write(" * may not use this file except in compliance with the License. You can obtain\n");
        out.write(" * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html\n");
        out.write(" * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific\n");
        out.write(" * language governing permissions and limitations under the License.\n");
        out.write(" *\n");
        out.write(" * When distributing the software, include this License Header Notice in each\n");
        out.write(" * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.\n");
        out.write(" * Sun designates this particular file as subject to the \"Classpath\" exception\n");
        out.write(" * as provided by Sun in the GPL Version 2 section of the License file that\n");
        out.write(" * accompanied this code.  If applicable, add the following below the License\n");
        out.write(" * Header, with the fields enclosed by brackets [] replaced by your own\n");
        out.write(" * identifying information: \"Portions Copyrighted [year]\n");
        out.write(" * [name of copyright owner]\"\n");
        out.write(" *\n");
        out.write(" * Contributor(s):\n");
        out.write(" *\n");
        out.write(" * If you wish your version of this file to be governed by only the CDDL or\n");
        out.write(" * only the GPL Version 2, indicate your decision by adding \"[Contributor]\n");
        out.write(" * elects to include this software in this distribution under the [CDDL or GPL\n");
        out.write(" * Version 2] license.\"  If you don't indicate a single choice of license, a\n");
        out.write(" * recipient has the option to distribute your version of this file under\n");
        out.write(" * either the CDDL, the GPL Version 2 or to extend the choice of license to\n");
        out.write(" * its licensees as provided above.  However, if you add GPL Version 2 code\n");
        out.write(" * and therefore, elected the GPL Version 2 license, then the option applies\n");
        out.write(" * only if the new code is made subject to such option by the copyright\n");
        out.write(" * holder.\n");
        out.write(" */\n");
    }
    private HashMap<String, String> genSingleFiles = new HashMap<String, String>();
    private HashMap<String, String> genListFiles = new HashMap<String, String>();
    private HashMap<String, String> genCommandResourceFiles = new HashMap<String, String>();

    public void generateList(ConfigModel model) throws IOException {

        String serverConfigName = model.targetTypeName.substring(model.targetTypeName.lastIndexOf(".") + 1,
                model.targetTypeName.length());

        if (genListFiles.containsKey(serverConfigName)) {
            return;
        }
        genListFiles.put(serverConfigName, serverConfigName);
        String beanName = getBeanName(serverConfigName);
        File file = new File(genDir + "/List" + beanName + "Resource.java");
        // File file = new File("/Users/ludo/tmp/" + beanName + "Resource.java");
        try {
            file.createNewFile();
        } catch (Exception e) {
            Logger.getLogger(GeneratorResource.class.getName()).log(Level.SEVERE, e.getMessage());
        }




        FileWriter fstream = new FileWriter(file);
        BufferedWriter out = new BufferedWriter(fstream);
        genHeader(out);
        out.write("package org.glassfish.admin.rest.resources;\n");
        out.write("import javax.ws.rs.*;\n");
//        out.write("import org.glassfish.admin.rest.TemplateResource;\n");
        out.write("import org.glassfish.admin.rest.TemplateListOfResource;\n");
//        out.write("import com.sun.jersey.api.core.ResourceContext;\n");
        out.write("import " + model.targetTypeName + ";\n");



        // out.write("@Path(\"/" + serverConfigName + "/\")\n");
        out.write("public class List" + beanName + "Resource extends TemplateListOfResource<" + beanName + "> {\n\n");

////        out.write("private List<" + beanName + "> entity;\n");
////        out.write("public void setEntity(List<" + beanName + "> p ){\n");
////        out.write("entity = p;\n");
////        out.write("}\n");
////
////
////        out.write("public  List<" + beanName + "> getEntity() {\n");
////        if (beanName.equals("Domain")) {
////            out.write("return RestService.theDomain;\n");
////        } else {
////            out.write("return entity;\n");
////
////        }
////        out.write("}\n");
        String keyAttributeName = null;
        if (model.key == null) {
            try {
                for (String s : model.getAttributeNames()) {//no key, by default use the name attr
                    if (s.equals("name")) {
                        keyAttributeName = getBeanName(s);
                    }
                }
                if (keyAttributeName == null)//nothing, so pick the ifrst one
                {
                    keyAttributeName = getBeanName(model.getAttributeNames().iterator().next());
                }
            } catch (Exception e) {
                keyAttributeName = "ThisIsAModelBug:NoKeyAttr"; //no attr choice fo a key!!! Error!!!
                } //firstone
            } else {
            keyAttributeName = getBeanName(model.key.substring(1, model.key.length()));
        }
        out.write("\n");
        out.write("\t@Path(\"{" + keyAttributeName + "}/\")\n");
        out.write("\tpublic " + beanName + "Resource get" + beanName + "Resource(@PathParam(\"" + keyAttributeName + "\") String id) {\n");
        out.write("\t\t" + beanName + "Resource resource = resourceContext.getResource(" + beanName + "Resource.class);\n");
        out.write("\t\tfor (" + beanName + " c: entity){\n");
        if (model.key == null) {
            out.write("//THIS KEY IS THE FIRST Attribute ONE ludo\n");

        }

        out.write("\t\t\t//Using '-' for back-slash in resource names\n");
        out.write("\t\t\t//For example, jndi names has back-slash in it.\n");
        out.write("\t\t\tif(c.get" + keyAttributeName + "().replace('/', '-').equals(id)){\n");
        out.write("\t\t\t\tresource.setEntity(c);\n");
        out.write("\t\t\t}\n");
        out.write("\t\t}\n");
        out.write("\t\treturn resource;\n");
        out.write("\t}\n\n");
///////ludo       generateCommand("List" + beanName, out);
        generateCommandResources("List" + beanName, out);

        out.write("\n");
        generateGetPostCommandMethod("List" + beanName, out);

        out.write("}\n");

        out.close();
        System.out.println("created:" + file.getAbsolutePath());

        generateSingle(model);


    }

    public void generateSingle(ConfigModel model) throws IOException {
        processRedirectsAnnotation(model);

        String serverConfigName = model.targetTypeName.substring(model.targetTypeName.lastIndexOf(".") + 1,
                model.targetTypeName.length());

        if (genSingleFiles.containsKey(serverConfigName)) {
            return;
        }
        genSingleFiles.put(serverConfigName, serverConfigName);
        String beanName = getBeanName(serverConfigName);
        File file = new File(genDir + "/" + beanName + "Resource.java");
        // File file = new File("/Users/ludo/tmp/" + beanName + "Resource.java");
        try {
            file.createNewFile();
        } catch (Exception e) {
            Logger.getLogger(GeneratorResource.class.getName()).log(Level.SEVERE, e.getMessage());
        }




        FileWriter fstream = new FileWriter(file);
        BufferedWriter out = new BufferedWriter(fstream);
        genHeader(out);
        out.write("package org.glassfish.admin.rest.resources;\n");
        out.write("import javax.ws.rs.*;\n");
//        out.write("import java.util.*;\n");
        out.write("import org.glassfish.admin.rest.TemplateResource;\n");
//        out.write("import org.glassfish.admin.rest.TemplateListOfResource;\n");
//        out.write("import com.sun.jersey.api.core.ResourceContext;\n");
        out.write("import " + model.targetTypeName + ";\n");



        if (beanName.equals("Domain")) {
            out.write("@Path(\"/" + "domain" + "/\")\n");
        }

        out.write("public class " + beanName + "Resource extends TemplateResource<" + beanName + "> {\n\n");

//        if (!beanName.equals("Domain")) {
//            out.write("private " + beanName + " entity;\n");
//            out.write("public void setEntity(" + beanName + " p ){\n");
//            out.write("entity = p;\n");
//            out.write("}\n");
//        }

        if (beanName.equals("Domain")) {
            out.write("@Override public " + beanName + " getEntity() {\n");
            out.write("return org.glassfish.admin.rest.RestService.getDomain();\n");
            out.write("}\n");
        }

     /////ludo   generateCommand(beanName, out);

        generateCommandResources(beanName, out);

        generateGetDeleteCommandMethod(beanName, out);

        Set<String> elem = model.getElementNames();

        for (String a : elem) {
            System.out.println("a= " + a);



            ConfigModel.Property prop = model.getElement(a);


            if (prop != null && prop.isLeaf()) {
                System.out.println("proxy.getElement(a).isLeaf() " + a);
                if (prop.isCollection()) {
                    //handle the CollectionLeaf config objects.
                    //JVM Options is an example of CollectionLeaf object.
                    String name = getBeanName(a);
                    out.write("\t@Path(\"" + a + "/\")\n");
                    out.write("\tpublic " + name + "Resource get" + name + "Resource() {\n");

                    out.write("\t\t" + name + "Resource resource = resourceContext.getResource(" + name + "Resource.class);\n");
                    out.write("\t\tresource.setEntity(getEntity().get" + name + "() );\n");
                    out.write("\t\treturn resource;\n");
                    out.write("\t}\n");

                    //create resource class
                    createCollectionLeafResourceFile(name);
                }
                System.out.println("proxy.getElement(a).isCollection() " + a);
            } else {
                ConfigModel.Node node = (ConfigModel.Node) prop;
                //String childbeanName = getBeanName(a);

                ConfigModel childModel = node.getModel();

                String getterName = getBeanName(a);

                System.out.println("Model.targetTypeName" + model.targetTypeName);
                System.out.println("newModel.targetTypeName" + childModel.targetTypeName);
                System.out.println("ConfigModel.Node node isCollection=" + prop.isCollection());
                System.out.println("ConfigModel.Node node isLeaf=" + prop.isLeaf());
                System.out.println("ConfigModel.Node node xlmname=" + prop.xmlName());
                if (childModel.targetTypeName.endsWith("Named")) {
                    a = "application";
                    getterName = "Applications";
                    try {
                        Class<?> subType = childModel.classLoaderHolder.get().loadClass(childModel.targetTypeName); ///  a shoulf be the typename


                        List<ConfigModel> lcm = document.getAllModelsImplementing(subType);
                        if (lcm != null) {
                            for (ConfigModel childmodel : lcm) {
                                System.out.println("***childmodel.targetTypeName" + childmodel.targetTypeName);
                                if (childmodel.targetTypeName.equals("com.sun.enterprise.config.serverbeans.Application")) {
                                    childModel = childmodel;
                                }
                            }
                        }
                    } catch (Exception e) {
                        Logger.getLogger(GeneratorResource.class.getName()).log(Level.SEVERE, e.getMessage());
                    }


                }

                String childbeanName = childModel.targetTypeName.substring(childModel.targetTypeName.lastIndexOf(".") + 1,
                        childModel.targetTypeName.length());

                if (!childModel.targetTypeName.endsWith("Resource")) {
                    String prefix = "";
                    if (prop.isCollection()) {
                        prefix = "List";
                    }

                    if (a.equals("*")) {
                        getterName = childbeanName + "s";
                    }

                    out.write("\t@Path(\"" + childModel.getTagName() + "/\")\n");
                    out.write("\tpublic " + prefix + childbeanName + "Resource get" + childbeanName + "Resource() {\n");

                    out.write("\t\t" + prefix + childbeanName + "Resource resource = resourceContext.getResource(" + prefix + childbeanName + "Resource.class);\n");
                    out.write("\t\tresource.setEntity(getEntity().get" + getterName + "() );\n");
                    out.write("\t\treturn resource;\n");
                    out.write("\t}\n");

                    if (prop.isCollection()) {
                        generateList(childModel);
                    } else {
                        generateSingle(childModel);

                    }


                } else {




                    try {
                        Class<?> subType = childModel.classLoaderHolder.get().loadClass(childModel.targetTypeName); ///  a shoulf be the typename


                        List<ConfigModel> lcm = document.getAllModelsImplementing(subType);
                        if (lcm != null) {
                            for (ConfigModel childmodel : lcm) {
                                System.out.println("--->targetTypeName=" + childmodel.targetTypeName);
                                String newName = childmodel.targetTypeName.substring(childmodel.targetTypeName.lastIndexOf(".") + 1,
                                        childmodel.targetTypeName.length());
                                out.write("@Path(\"" + childmodel.getTagName() + "/\")\n");
                                out.write("public List" + newName + "Resource get" + newName + "Resource() {\n");
                                out.write("List" + newName + "Resource resource = resourceContext.getResource(List" + newName + "Resource.class);\n");
                                out.write("java.util.List<com.sun.enterprise.config.serverbeans.Resource> l = entity.getResources();\n");
                                out.write("java.util.List<" + childmodel.targetTypeName + "> newList = new java.util.ArrayList();\n");
                                out.write("for (com.sun.enterprise.config.serverbeans.Resource r: l){\n");
                                out.write("try {\n");
                                out.write("if (r instanceof " + childmodel.targetTypeName + ") {\n");
                                out.write("newList.add((" + childmodel.targetTypeName + ")r);\n");
                                out.write("}\n");
                                out.write("} catch (Exception e){\n");

                                out.write("}\n");
                                out.write("}\n");
                                out.write("resource.setEntity(newList );\n");
                                out.write("return resource;\n");
                                out.write("}\n\n\n");
                                generateList(childmodel);



                            }
                        }

                        //com.sun.enterprise.config.serverbeans.CustomResource

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }


            }

        }


        out.write("}\n");

        out.close();
        System.out.println("created:" + file.getAbsolutePath());


    }


    private String getBeanName(String elementName) {
        String ret = "";
        boolean nextisUpper = true;


        for (int i = 0; i < elementName.length(); i++) {
            if (nextisUpper == true) {
                ret = ret + elementName.substring(i, i + 1).toUpperCase();
                nextisUpper = false;

            } else {
                if (elementName.charAt(i) == '-') {
                    nextisUpper = true;
                } else {
                    nextisUpper = false;
                    ret = ret + elementName.substring(i, i + 1);

                }
            }
        }

        return ret;
    }


    void generateGetPostCommandMethod(String resourceName, BufferedWriter out) throws IOException {
        String commandName = getPostCommandName(resourceName);
        out.write("@Override\n");
        out.write("public String getPostCommand() {\n");
        if (commandName != null) {
            out.write("\treturn \"" + commandName + "\";\n");
        } else {
            out.write("\treturn " + commandName + ";\n");
        }
        out.write("}\n");      
        }


    private String getPostCommandName(String resourceName) {
        //FIXME - fetch command name from config bean(RestRedirect annotation).
        for (int i = 0; i < MappingConfigBeansToPOSTCommands.length; i++) {
            if (resourceName.equals(MappingConfigBeansToPOSTCommands[i][0])) {
                    return MappingConfigBeansToPOSTCommands[i][1];
            }
        }
        return null; //POST is not mapped to any create command for this resource
    }


    void generateGetDeleteCommandMethod(String resourceName, BufferedWriter out) throws IOException {
        String commandName = getDeleteCommandName(resourceName);
        if (commandName != null) {
            out.write("@Override\n");
            out.write("public String getDeleteCommand() {\n");
            out.write("\treturn \"" + commandName + "\";\n");
            out.write("}\n");
        }
    }


    private String getDeleteCommandName(String resourceName) {
        //FIXME - fetch command name from config bean(RestRedirect annotation).
        //This delete commands meta-data witll move to com.sun.grizzly.config.dom.* config beans
        for (int i = 0; i < MappingConfigBeansToDELETECommands.length; i++) {
            if (resourceName.equals(MappingConfigBeansToDELETECommands[i][0])) {
                    return MappingConfigBeansToDELETECommands[i][1];
            }
        }
        return null;
    }


    private String[] getCollectionLeafResourceInfo(String resourceName) {
        for (int i = 0; i < ConfigBeansToCommands.length; i++) {
            if (resourceName.equals(ConfigBeansToCommands[i][0])) {
                    return ConfigBeansToCommands[i];
            }
        }
        return null;
    }


    /*
     * temporary mapping to add Admin Commands to some of our configbeans
     *
     * */
   
/*   private static String MappingConfigBeansToCommands[][] = {
        {"Domain", "stop-domain"},
        {"Domain", "restart-domain"},
        {"Domain", "uptime"},
        {"Domain", "version"},
        {"Domain", "rotate-log"},
        {"Domain", "get-host-and-port"},
        {"ListApplication", "deploy"},
        {"Application", "redeploy"},
        //  {"ListExternalJndiResource", ""},
        //{"ListWorkSecurityMap", ""},
        //{"ListPersistenceManagerFactoryResource", ""},

        //{"", "create-connector-work-security-map"},
        //  {"", "create-file-user"},
        //    {"", "create-jmsResource"},
        //    {"", "create-jmsdest"},
        //   {"", "create-jvm-options"},
        //    {"", "create-password-alias"},
        ////    {"", "create-ssl"},
        {"ConnectionPool", "ping-connection-pool"},/*
    addResources
    change-admin-password
    disable
    enable
    generate-jvm-report
    get
    get-client-stubs
    // get-host-and-port
    //redeploy
    //undeploy
    // ping-connection-pool

    // create-admin-object
    //create-connector-connection-pool
    // create-connectorResource
    //create-customResource
    //create-javamailResource
    //create-jdbc-connection-pool
    //create-jdbcResource
    // createResource-adapter-config
    delete-admin-object
    delete-audit-module
    delete-auth-realm
    delete-connector-connection-pool
    delete-connectorResource
    delete-connector-work-security-map
    delete-customResource
    delete-file-user
    delete-http-listener
    delete-iiop-listener
    delete-javamailResource
    delete-jdbc-connection-pool
    delete-jdbcResource
    delete-jms-host
    monitor
    delete-jmsResource
    delete-jmsdest
    delete-jvm-options
    delete-message-security-provider
    delete-password-alias
    delete-profiler
    deleteResource-adapter-config
    deleteResource-ref
    update-file-user
    delete-ssl
    update-password-alias
    delete-system-property
    delete-virtual-server


     };
*/

    private static String MappingConfigBeansToPOSTCommands[][] = {
        {"ListApplication", "deploy"},
        {"Application", "redeploy"},
        {"ListAdminObjectResource", "create-admin-object"},
        {"ListCustomResource", "create-custom-resource"},
        {"ListJdbcResource", "create-jdbc-resource"},
        {"ListJdbcConnectionPool", "create-jdbc-connection-pool"},
        {"ListConnectorResource", "create-connector-resource"},
        {"ListMailResource", "create-javamail-resource"},
        {"ListResourceAdapterConfig", "create-resource-adapter-config"},
        {"ListConnectorConnectionPool", "create-connector-connection-pool"},
        {"ListAuthRealm", "create-auth-realm"},
        {"ListAuditModule", "create-audit-module"},
        {"ListHttpListener", "create-http-listener"},
        {"ListIiopListener", "create-iiop-listener"},
        {"ListNetworkListener", "create-network-listener"},
        {"ListTransport", "create-transport"},
        {"ListProtocol", "create-protocol"},
        {"ListJmsHost", "create-jms-host"},
        {"ListMessageSecurityConfig", "create-message-security-provider"},
        {"JavaConfig", "create-profiler"},
        {"ListResourceRef", "create-resource-ref"},
        {"ListSystemProperty", "create-system-properties"},
        {"ListVirtualServer", "create-virtual-server"},
        {"ListThreadPool", "create-threadpool"}
     };


    private static String MappingConfigBeansToDELETECommands[][] = {
        {"Transport", "delete-transport"},
        {"ThreadPool", "delete-threadpool"},
        {"NetworkListener", "delete-network-listener"},
        {"Protocol", "delete-protocol"}
    };


    //This map is used to generate CollectionLeaf resources.
    //Example: JVM Options. This information will eventually move to config bean-
    //JavaConfig or JvmOptionBag
    private static String ConfigBeansToCommands[][] = {
        //{config-bean, post command, delete command, disaplay name}
        {"JvmOptions", "create-jvm-options", "delete-jvm-options", "JvmOption"}
    };


    private static String ConfigBeansToCommandResourcesMap[][] = {
        //{config-bean, command, method, resource-path, command-action, command-params...}
        {"Domain", "stop-domain", "POST", "stop", "Stop"},
        {"Domain", "restart-domain", "POST", "restart", "Restart"},
        {"Domain", "uptime", "GET", "uptime", "Uptime"},
        {"Domain", "version", "GET", "version", "Version"},
        {"Domain", "rotate-log", "POST", "rotate-log", "RotateLog"},
        {"Domain", "get-host-and-port", "GET", "host-port", "HostPort"},
        ///{"ListApplication", "deploy"},
        ///{"Application", "redeploy"},
        {"Application", "enable", "POST", "enable", "Enable", "id=$parent"},
        {"Application", "disable", "POST", "disable", "Disable", "id=$parent"},
        {"ConnectionPool", "ping-connection-pool", "GET", "ping", "Ping"},
        {"IiopService", "create-ssl", "POST", "create-ssl", "Create", "type=iiop-service"},
        {"IiopService", "delete-ssl", "DELETE", "delete-ssl", "Delete", "type=iiop-service"},
        {"IiopListener", "create-ssl", "POST", "create-ssl", "Create", "id=$parent", "type=iiop-listener"},
        {"IiopListener", "delete-ssl", "DELETE", "delete-ssl", "Delete", "id=$parent", "type=iiop-listener"},
        {"AuthRealm", "create-file-user", "POST", "create-user", "Create", "authrealmname=$parent"},
        {"AuthRealm", "delete-file-user", "DELETE", "delete-user", "Delete", "authrealmname=$parent"},
        {"AuthRealm", "list-file-users", "GET", "list-users", "List", "authrealmname=$parent"},
        {"NetworkListener", "create-ssl", "POST", "create-ssl", "Create", "id=$parent", "type=http-listener"},
        {"NetworkListener", "delete-ssl", "DELETE", "delete-ssl", "Delete", "id=$parent", "type=http-listener"},
        {"Protocol", "create-http", "POST", "create-http", "Create", "id=$parent"},
        {"Protocol", "delete-http", "DELETE", "delete-http", "Delete", "id=$parent"}
    };


    private void generateCommandResources(String resourceName,
        BufferedWriter out) throws IOException {

        if (genCommandResourceFiles.containsKey(resourceName)) {
            return;
        }
        genCommandResourceFiles.put(resourceName, resourceName);


        String commandResourcesPaths = "{";
        for (int i = 0; i < ConfigBeansToCommandResourcesMap.length; i++) {
            if (resourceName.equals(ConfigBeansToCommandResourcesMap[i][0])) {
                if (commandResourcesPaths.length() > 1) {
                    commandResourcesPaths = commandResourcesPaths + ", ";
                }
                commandResourcesPaths = commandResourcesPaths + "{" +
                    "\"" + ConfigBeansToCommandResourcesMap[i][3] + "\"" + ", " +
                        "\"" + ConfigBeansToCommandResourcesMap[i][2] + "\"" + "}";

                String commandResourceFileName = genDir + "/" + resourceName +
                    getBeanName(ConfigBeansToCommandResourcesMap[i][3]) +
                        "Resource.java";
                String commandResourceName = resourceName +
                    getBeanName(ConfigBeansToCommandResourcesMap[i][3]) +
                        "Resource";

                //generate command resource for the resource- resourceName
                createCommandResourceFile(commandResourceFileName,
                    commandResourceName, ConfigBeansToCommandResourcesMap[i]);

                //define method with @Path in resource- resourceName
                out.write("@Path(\"" + ConfigBeansToCommandResourcesMap[i][3] + "/\")\n");
                out.write("public " + commandResourceName + " get" +
                    commandResourceName + "() {\n");
                out.write(commandResourceName + " resource = resourceContext.getResource(" + commandResourceName + ".class);\n");
                out.write("return resource;\n");
                out.write("}\n\n");
            }
        }
        commandResourcesPaths = commandResourcesPaths + "}";

        //define method to return command resource paths. only if needed
        if (!commandResourcesPaths.equals("{}")){
        out.write("@Override\n");
        out.write("public String[][] getCommandResourcesPaths() {\n");
        out.write("return new String[][]" +  commandResourcesPaths + ";\n");
        out.write("}\n\n");
        }
    }

    private void createCommandResourceFile(String commandResourceFileName,
        String commandResourceName, String [] configBeansToCommandResourcesArray)
            throws IOException {
        String resourceName = configBeansToCommandResourcesArray[0] +
            getBeanName(configBeansToCommandResourcesArray[3]);
        String commandName = configBeansToCommandResourcesArray[1];
        String commandDisplayName = configBeansToCommandResourcesArray[3];
        String commandMethod = configBeansToCommandResourcesArray[2];
        String commandAction = configBeansToCommandResourcesArray[4];

        File file = new File(commandResourceFileName);
        try {
            file.createNewFile();
        } catch (Exception e) {
            Logger.getLogger(GeneratorResource.class.getName()).log(Level.SEVERE, e.getMessage());
        }

        FileWriter fstream = new FileWriter(file);
        BufferedWriter out = new BufferedWriter(fstream);

        //header
        genHeader(out);

        //package
        out.write("package org.glassfish.admin.rest.resources;\n\n");

        //imports
        out.write("import java.util.HashMap;\n\n");
        out.write("import javax.ws.rs.*;\n");
        out.write("import javax.ws.rs.core.Context;\n");
        out.write("import javax.ws.rs.core.HttpHeaders;\n");
        out.write("import javax.ws.rs.core.MediaType;\n");
        out.write("import javax.ws.rs.core.Response;\n");
        out.write("import javax.ws.rs.core.UriInfo;\n\n");
        out.write("import com.sun.enterprise.util.LocalStringManagerImpl;\n\n");
        out.write("import org.glassfish.admin.rest.provider.OptionsResult;\n");
        out.write("import org.glassfish.admin.rest.provider.MethodMetaData;\n");
        if (commandMethod.equals("GET")) {
            out.write("import org.glassfish.admin.rest.provider.StringResult;\n");
        }
        out.write("import org.glassfish.admin.rest.Constants;\n");
        out.write("import org.glassfish.admin.rest.ResourceUtil;\n");
        out.write("import org.glassfish.admin.rest.RestService;\n");
        out.write("import org.glassfish.api.ActionReport;\n\n");

        //class header
        out.write("public class " + commandResourceName + " {\n\n");

        //constructor
        out.write("public " + commandResourceName + "() {\n");
        out.write("__resourceUtil = new ResourceUtil();\n");
        out.write("}\n");

        //create command method
        if (commandMethod.equals("GET")) {
            //get method
            createCommandGetMethod(commandName, commandMethod, out);

            //create options method
            createCommandOptionsMethod(out, Constants.QUERY_PARAMETER);
        } else {
            //post, put or delete method
            createCommandMethod(commandMethod, out);

            //get method
            createGetMethod(out);

            //create options method
            createCommandOptionsMethod(out, Constants.MESSAGE_PARAMETER);
        }


        //variable declarations
        out.write("public final static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(ResourceUtil.class);\n");
        out.write("@Context\n");
        out.write("protected HttpHeaders requestHeaders;\n");
        out.write("@Context\n");
        out.write("protected UriInfo uriInfo;\n\n");
        out.write("private static final String resourceName = \"" + resourceName + "\";\n");
        out.write("private static final String commandName = \"" + commandName + "\";\n");
        out.write("private static final String commandDisplayName = \"" + commandDisplayName + "\";\n");
        out.write("private static final String commandMethod = \"" + commandMethod + "\";\n");
        out.write("private static final String commandAction = \"" + commandAction + "\";\n");

        boolean isLinkedToParent = false;
        if (configBeansToCommandResourcesArray.length > 5 ) {
            out.write("private HashMap<String, String> commandParams =\n");
            out.write("new HashMap<String, String>() {{\n");
            for (int i=5; i <= configBeansToCommandResourcesArray.length - 1; i++) {
                String[] name_value = stringToArray(configBeansToCommandResourcesArray[i], "=");
                if (name_value[1].equals(Constants.PARENT_NAME_VARIABLE)) {
                    isLinkedToParent = true;
                }
                out.write("put(\"" + name_value[0] + "\",\"" + name_value[1] + "\");\n");
            }

            out.write("}};\n");
        } else {
            out.write("private HashMap<String, String> commandParams = null;\n");
        }
        out.write("private static final boolean isLinkedToParent = " + isLinkedToParent + ";\n");
        out.write("private ResourceUtil __resourceUtil;\n");
        out.write("}\n");

        out.close();
        System.out.println("created:" + file.getAbsolutePath());
    }


    private void createCollectionLeafResourceFile(String beanName) throws IOException {
        String resourceFileName = genDir + "/" + beanName + "Resource.java";
        String resourceName = beanName + "Resource";

        File file = new File(resourceFileName);
        try {
            file.createNewFile();
        } catch (Exception e) {
            Logger.getLogger(GeneratorResource.class.getName()).log(Level.SEVERE, e.getMessage());
        }
        FileWriter fstream = new FileWriter(file);
        BufferedWriter out = new BufferedWriter(fstream);

        //header
        genHeader(out);

        //package
        out.write("package org.glassfish.admin.rest.resources;\n\n");

        //imports
        out.write("import org.glassfish.admin.rest.CollectionLeafResource;\n\n");

        //class header
        out.write("public class " + resourceName + " extends CollectionLeafResource {\n\n");

        String[] collectionLeafResourceInfo = getCollectionLeafResourceInfo(beanName);

        if (collectionLeafResourceInfo != null) {
            //post method
            if ((collectionLeafResourceInfo[1] != null) && (!collectionLeafResourceInfo[1].equals(""))) {
                out.write("@Override\n");
                out.write("protected String getPostCommand(){\n");
                out.write("return \"" + collectionLeafResourceInfo[1] + "\";\n");
                out.write("}\n");
            }

            //delete method
            if ((collectionLeafResourceInfo[2] != null) && (!collectionLeafResourceInfo[2].equals(""))) {
                out.write("@Override\n");
                out.write("protected String getDeleteCommand(){\n");
                out.write("return \"" + collectionLeafResourceInfo[2] + "\";\n");
                out.write("}\n");
            }

            //display name method
            out.write("@Override\n");
            out.write("protected String getName(){\n");
            out.write("return \"" + collectionLeafResourceInfo[3] + "\";\n");
            out.write("}\n");
        }

        out.write("}\n");
        out.close();
    }


    private void createCommandMethod(String commandMethod, BufferedWriter out) throws IOException {
        out.write("@" + commandMethod + "\n");
        out.write("@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_FORM_URLENCODED})\n");
        out.write("public Response executeCommand(HashMap<String, String> data) {\n");
        out.write("try {\n");
        out.write("if (data.containsKey(\"error\")) {\n");
        out.write("String errorMessage = localStrings.getLocalString(\"rest.request.parsing.error\", \"Unable to parse the input entity. Please check the syntax.\");\n");
        out.write("return __resourceUtil.getResponse(400, /*parsing error*/\n errorMessage, requestHeaders, uriInfo);\n");
        out.write("}\n\n");

        out.write("if (commandParams != null) {\n");
        out.write("//formulate parent-link attribute for this command resource\n");
        out.write("//Parent link attribute may or may not be the id/target attribute\n");
        out.write("if (isLinkedToParent) {\n");
        out.write("__resourceUtil.resolveParentParamValue(commandParams, uriInfo);\n");
        out.write("}\n\n");
        out.write("data.putAll(commandParams);\n");
        out.write("}\n\n");
        out.write("__resourceUtil.adjustParameters(data);\n\n");
        out.write("__resourceUtil.purgeEmptyEntries(data);\n\n");

        out.write("ActionReport actionReport = __resourceUtil.runCommand(commandName, data, RestService.getHabitat());\n\n");
        out.write("ActionReport.ExitCode exitCode = actionReport.getActionExitCode();\n\n");

        out.write("if (exitCode == ActionReport.ExitCode.SUCCESS) {\n");
        out.write("String successMessage = localStrings.getLocalString(\"rest.request.success.message\",\n");
        out.write("\"{0} of {1} executed successfully.\", new Object[] {commandMethod, uriInfo.getAbsolutePath()});\n");
        out.write("return __resourceUtil.getResponse(200, /*200 - ok*/\n successMessage, requestHeaders, uriInfo);\n");
        out.write("}\n\n");

        out.write("String errorMessage = actionReport.getMessage();\n");
        out.write("return __resourceUtil.getResponse(400, /*400 - bad request*/\n errorMessage, requestHeaders, uriInfo);\n");
        out.write("} catch (Exception e) {\n");
        out.write("throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);\n");
        out.write("}\n");
        out.write("}\n");

        out.write("//Handle POST request without any entity(input).\n");
        out.write("//Do not care what the Content-Type is.\n");
        out.write("@" + commandMethod + "\n");
        out.write("public Response executeCommand() {\n");
        out.write("try {\n");
        out.write("return executeCommand(new HashMap<String, String>());\n");
        out.write("} catch (Exception e) {\n");
        out.write("throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);\n");
        out.write("}\n");
        out.write("}\n");


        //hack-1 : support delete method for html
        //Currently, browsers do not support delete method. For html media,
        //delete operations can be supported through POST. Redirect html
        //client POST request for delete operation to DELETE method.

        //In case of delete command reosurce, we will also create post method
        //which simply forwards the request to delete method. Only in case of
        //html client delete request is routed through post. For other clients
        //delete request is directly handled by delete method.
        if (commandMethod.equals("DELETE")) {
            out.write("//hack-1 : support delete method for html\n");
            out.write("//Currently, browsers do not support delete method. For html media,\n");
            out.write("//delete operations can be supported through POST. Redirect html\n");
            out.write("//client POST request for delete operation to DELETE method.\n\n");

            out.write("//In case of delete command reosurce, we will also create post method\n");
            out.write("//which simply forwards the request to delete method. Only in case of\n");
            out.write("//html client delete request is routed through post. For other clients\n");
            out.write("//delete request is directly handled by delete method.\n");

            out.write("@" + "POST" + "\n");
            out.write("@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_FORM_URLENCODED})\n");
            out.write("public Response hack(HashMap<String, String> data) {\n");
            out.write("if ((data.containsKey(\"operation\")) &&\n");
            out.write("(data.get(\"operation\").equals(\"__deleteoperation\"))) {\n");
            out.write("data.remove(\"operation\");\n");
            out.write("}\n");
            out.write("return executeCommand(data);\n");
            out.write("}\n");
        }
    }


    private void createGetMethod(BufferedWriter out)
                throws IOException {
        out.write("@" + "GET" + "\n");
        out.write("@Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})\n");
        out.write("public org.glassfish.admin.rest.provider.CommandResourceGetResult get() {\n");
        out.write("try {\n");
        out.write("return new org.glassfish.admin.rest.provider.CommandResourceGetResult(resourceName, commandName, commandDisplayName, commandMethod, commandAction, options());\n");
        out.write("} catch (Exception e) {\n");
        out.write("throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);\n");
        out.write("}\n");
        out.write("}\n");
    }


    private void createCommandGetMethod(String commandName,
            String commandMethod, BufferedWriter out) throws IOException {
        CommandRunner cr = RestService.getHabitat().getComponent(CommandRunner.class);
        CommandModel cm = null;
        try {
            cm = cr.getModel(commandName, RestService.logger);
        } catch (Exception e) {
            System.out.println("Error - Command Unknown: " + commandName);
            return;
        }
        if (cm == null) {
            System.out.println("Error - Command Unknown: " + commandName);
            return;
        }
        java.util.Collection<CommandModel.ParamModel> params = cm.getParameters();

        out.write("@" + commandMethod + "\n");//commandMethod - GET
        out.write("@Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_FORM_URLENCODED})\n");
        out.write("public StringResult executeCommand(\n");
        boolean first = true;
        for (CommandModel.ParamModel pm : params) {
            if (first == false) {
                out.write(" ,\n");
            }
            first = false;
            out.write("\t @QueryParam(\"" + pm.getName() + "\") ");
            out.write(" @DefaultValue(\"" + pm.getParam().defaultValue() + "\") ");
            out.write(" String " + getBeanName(pm.getName()) + " \n");
        }
        out.write(" \t) {\n");

        out.write("try {\n");
        out.write("\tjava.util.Properties properties = new java.util.Properties();\n");
        for (CommandModel.ParamModel pm : params) {
            out.write("\tif (!" + getBeanName(pm.getName()) + ".isEmpty()) {\n");
            out.write("\t\tproperties.put(\"" + pm.getName() + "\", " + getBeanName(pm.getName()) + ");\n");
            out.write("\t}");
        }

        out.write("if (commandParams != null) {\n");
        out.write("//formulate parent-link attribute for this command resource\n");
        out.write("//Parent link attribute may or may not be the id/target attribute\n");
        out.write("if (isLinkedToParent) {\n");
        out.write("__resourceUtil.resolveParentParamValue(commandParams, uriInfo);\n");
        out.write("}\n");
        out.write("properties.putAll(commandParams);\n");
        out.write("}\n\n");

        out.write("ActionReport actionReport = __resourceUtil.runCommand(commandName, properties, RestService.getHabitat());\n\n");
        out.write("ActionReport.ExitCode exitCode = actionReport.getActionExitCode();\n\n");
        out.write("StringResult results = new StringResult(commandName, __resourceUtil.getMessage(actionReport), options());\n");
        out.write("if (exitCode == ActionReport.ExitCode.SUCCESS) {\n");
        out.write("results.setStatusCode(200); /*200 - ok*/\n");
        out.write("} else {\n");
        out.write("results.setStatusCode(400); /*400 - bad request*/\n");
        out.write("results.setIsError(true);\n");
        out.write("results.setErrorMessage(actionReport.getMessage());\n");
        out.write("}\n\n");

        out.write("return results;\n\n");

        out.write("} catch (Exception e) {\n");
        out.write("throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);\n");
        out.write("}\n");
        out.write("}\n");
    }


    private void createCommandOptionsMethod(BufferedWriter out, int parameterType) throws IOException {
        out.write("@OPTIONS\n");
        out.write("@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_XML})\n");
        out.write("public OptionsResult options() {\n");
        out.write("OptionsResult optionsResult = new OptionsResult(resourceName);\n");
        out.write("try {\n");
        out.write("//command method metadata\n");
        out.write("MethodMetaData methodMetaData = __resourceUtil.getMethodMetaData(\n");
        if (parameterType == Constants.QUERY_PARAMETER) {
             out.write("commandName, commandParams, Constants.QUERY_PARAMETER, RestService.getHabitat(), RestService.logger);\n");
        } else {
            //message parameter
            out.write("commandName, commandParams, Constants.MESSAGE_PARAMETER, RestService.getHabitat(), RestService.logger);\n");

            //GET meta data
            out.write("//GET meta data\n");
            out.write("optionsResult.putMethodMetaData(\"GET\", new MethodMetaData());\n");
        }

        out.write("optionsResult.putMethodMetaData(commandMethod, methodMetaData);\n");
        out.write("} catch (Exception e) {\n");
        out.write("throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);\n");
        out.write("}\n\n");

        out.write("return optionsResult;\n");
        out.write("}\n\n");
    }


    //This method converts a string into stringarray, uses the delimeter as the
    //separator character.
    private static String[] stringToArray(String str, String delimiter) {
        String[] retString = new String[0];

        if (str != null) {
            if(delimiter != null) {
                StringTokenizer tokens = new StringTokenizer(str, delimiter);
                retString = new String[tokens.countTokens()];
                int i = 0;
                while(tokens.hasMoreTokens()) {
                    retString[i++] = tokens.nextToken();
                }
            }
        }
        return retString;
    }
}
TOP

Related Classes of org.glassfish.admin.rest.GeneratorResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.