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

grails.ui.shell.GrailsShell.groovy Maven / Gradle / Ivy

There is a newer version: 2023.2.0-M1
Show newest version
/*
 * Copyright 2014-2024 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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 grails.ui.shell

import groovy.transform.CompileStatic
import groovy.transform.InheritConstructors
import org.apache.groovy.groovysh.Groovysh
import org.apache.groovy.groovysh.InteractiveShellRunner
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.tools.shell.IO
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.core.io.ResourceLoader

import grails.binding.GroovyShellBindingCustomizer
import grails.boot.Grails
import grails.core.GrailsApplication
import grails.persistence.support.PersistenceContextInterceptor

/**
 * A Shell
 *
 * @author Graeme Rocher
 * @author Michael Yan
 * @since 3.0
 */
@CompileStatic
@InheritConstructors
class GrailsShell extends Grails {

    static final String[] BANNER = [
            '  _____                         ______       ____',
            ' / ___/______  ___ _  ____ __  / __/ /  ___ / / /',
            '/ (_ / __/ _ \\/ _ \\ |/ / // / _\\ \\/ _ \\/ -_) / /',
            '\\___/_/  \\___/\\___/___/\\_, / /___/_//_/\\__/_/_/',
            '                      /___/'
    ]

    GrailsShell(Class... sources) {
        super(sources)
    }

    GrailsShell(ResourceLoader resourceLoader, Class... sources) {
        super(resourceLoader, sources)
    }

    @Override
    ConfigurableApplicationContext run(String... args) {
        ConfigurableApplicationContext applicationContext = super.run(args)

        startConsole(applicationContext)

        applicationContext
    }

    protected void startConsole(ConfigurableApplicationContext context) {
        GrailsApplication grailsApplication = context.getBean(GrailsApplication)
        Collection bindingCustomizers = context.getBeansOfType(GroovyShellBindingCustomizer).values()
        Set packageNames = (getAllSources() as Set)*.package.name as Set

        Binding binding = new Binding()
        binding.setVariable('app', this)
        binding.setVariable('ctx', context)
        binding.setVariable('config', grailsApplication.getConfig())
        binding.setVariable(GrailsApplication.APPLICATION_ID, grailsApplication)
        bindingCustomizers?.each { customizer -> customizer.customize(binding) }

        IO io = new IO()
        io.verbosity = IO.Verbosity.VERBOSE
        Groovysh groovysh = new Groovysh(binding, io) {

            CompilerConfiguration configuration = CompilerConfiguration.DEFAULT
            Closure beforeExecution
            Closure afterExecution

            @Override
            void displayWelcomeBanner(InteractiveShellRunner runner) {
                io.out.println()

                for (String line : BANNER) {
                    io.out.println(String.format('@|green  %s|@', line))
                }

                io.out.println('-' * (95 - 1))
                io.out.println(String.format('Groovy: %s, JVM: %s',
                        GroovySystem.version,
                        System.properties['java.version']))
                io.out.println("Type '@|bold :help|@' or '@|bold :h|@' for help.")
                io.out.println('-' * (95 - 1))
            }

            @Override
            Object execute(String line) {
                if (!isExecutable(line) && beforeExecution) {
                    beforeExecution()
                }

                Object result = super.execute(line)

                if (!isExecutable(line) && afterExecution) {
                    afterExecution()
                }

                result
            }

        }

        Collection interceptors = context.getBeansOfType(PersistenceContextInterceptor).values()
        groovysh.beforeExecution = {
            for (i in interceptors) {
                i.init()
            }
        }
        groovysh.afterExecution = {
            for (i in interceptors) {
                i.destroy()
            }
        }
        groovysh.historyFull = true
        groovysh.imports.addAll(packageNames.collect({ it + '.*' }).toList())
        groovysh.run('')
    }

    /**
     * Static helper that can be used to run a {@link Grails} from the
     * specified source using default settings.
     * @param source the source to load
     * @param args the application arguments (usually passed from a Java main method)
     * @return the running {@link org.springframework.context.ApplicationContext}
     */
    static ConfigurableApplicationContext run(Class source, String... args) {
        run([source] as Class[], args)
    }

    /**
     * Static helper that can be used to run a {@link Grails} from the
     * specified sources using default settings and user supplied arguments.
     * @param sources the sources to load
     * @param args the application arguments (usually passed from a Java main method)
     * @return the running {@link org.springframework.context.ApplicationContext}
     */
    static ConfigurableApplicationContext run(Class[] sources, String[] args) {
        new GrailsShell(sources).run(args)
    }

    /**
     * Main method to run an existing Application class
     *
     * @param args The first argument is the Application class name
     */
    static void main(String[] args) {
        if (args) {
            Class applicationClass = Thread.currentThread().contextClassLoader.loadClass(args[0])
            GrailsShell.run(applicationClass, args)
        }
        else {
            System.err.println('Missing application class name argument')
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy