2010-06-02 7 views
6

Ich muss alle verfügbaren Aktionen von jedem Controller in meiner Web-App auslesen. Der Grund dafür ist ein Autorisierungssystem, bei dem ich den Benutzern eine Liste der erlaubten Aktionen geben muss.Alle Aktionen in einem Grails-Controller auslesen

Zum Beispiel: Benutzer xyz hat die Berechtigung zum Ausführen der Aktionen show, list, search. Benutzer admin hat die Berechtigung zum Ausführen der Aktionen bearbeiten, löschen etc.

Ich muss alle Aktionen von einem Controller auslesen. Hat jemand eine Idee?

Antwort

9

Dies erstellt eine Liste von Karten (die 'Daten' Variable) mit Controller-Informationen. Jedes Element in der Liste ist eine Map mit den Schlüsseln "Controller", entsprechend dem URL-Namen des Controllers (zB BookController -> 'book'), controllername entsprechend dem Klassennamen ('BookController') und 'actions' entsprechend a Liste der Aktionsnamen für diesen Controller:

import org.springframework.beans.BeanWrapper 
import org.springframework.beans.PropertyAccessorFactory 

def data = [] 
for (controller in grailsApplication.controllerClasses) { 
    def controllerInfo = [:] 
    controllerInfo.controller = controller.logicalPropertyName 
    controllerInfo.controllerName = controller.fullName 
    List actions = [] 
    BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(controller.newInstance()) 
    for (pd in beanWrapper.propertyDescriptors) { 
     String closureClassName = controller.getPropertyOrStaticPropertyOrFieldValue(pd.name, Closure)?.class?.name 
     if (closureClassName) actions << pd.name 
    } 
    controllerInfo.actions = actions.sort() 
    data << controllerInfo 
} 
+0

Ist dieser Code noch 2 mit Grails arbeiten? Ich meine, in Grails2 sind Controller keine Verschlüsse mehr – fabien7474

+3

Verschlüsse werden noch unterstützt, aber Methoden werden bevorzugt. I 2.0 Sie können nach Methoden mit der @ grails.web.Action Annotation suchen –

+0

@BurtBeckwith Können wir beforeInterceptor von controllerClasses verwenden? – user1791574

4

Grails unterstützt keine direkte Methode, dies zu tun. Allerdings konnte ich von Methoden zur Verfügung grails zusammen ein Rätsel setzen und haben zu dieser Lösung kommen:

def actions = new HashSet<String>() 
def controllerClass = grailsApplication.getArtefactInfo(ControllerArtefactHandler.TYPE) 
         .getGrailsClassByLogicalPropertyName(controllerName) 
for (String uri : controllerClass.uris) { 
    actions.add(controllerClass.getMethodActionName(uri)) 
} 

Variablen grailsApplication und controller injiziert von Grails. Als Controller selbst erforderlichen Methoden nicht hat, dieser Code ruft seine controllerClass (siehe GrailsControllerClass), das, was wir brauchen ist: Eigenschaft uris und Methode getMethodActionName

4

Hier ist ein Beispiel, das mit Grails 2, dh es definiert wird erfassen Aktionen funktioniert entweder als Methoden oder Verschlüsse

import org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass 
import java.lang.reflect.Method 
import grails.web.Action 

// keys are logical controller names, values are list of action names 
// that belong to that controller 
def controllerActionNames = [:] 

grailsApplication.controllerClasses.each { DefaultGrailsControllerClass controller -> 

    Class controllerClass = controller.clazz 

    // skip controllers in plugins 
    if (controllerClass.name.startsWith('com.mycompany')) { 
     String logicalControllerName = controller.logicalPropertyName 

     // get the actions defined as methods (Grails 2) 
     controllerClass.methods.each { Method method -> 

      if (method.getAnnotation(Action)) { 
       def actions = controllerActionNames[logicalControllerName] ?: [] 
       actions << method.name 

       controllerActionNames[logicalControllerName] = actions 
      } 
     } 
    } 
} 
3

Um eine Liste aller Methoden mit Aktionsnamen ausdrucken:

grailsApplication.controllerClasses.each { 
       it.getURIs().each {uri -> 
       println "${it.logicalPropertyName}.${it.getMethodActionName(uri)}" 
       } 
    }