/* * Copyright 2014 original 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 * * http://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 org.grails.compiler.injection; import grails.plugins.GrailsPluginInfo; import grails.util.GrailsNameUtils; import org.codehaus.groovy.ast.ClassCodeVisitorSupport; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.PropertyNode; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.control.CompilationFailedException; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.grails.io.support.Resource; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * Reads plugin info from the AST * * @author Graeme Rocher * @since 3.0 */ class PluginAstReader { private BasicGrailsPluginInfo pluginInfo; public PluginAstReader() { this.pluginInfo = new BasicGrailsPluginInfo(); } GrailsPluginInfo getPluginInfo() { return this.pluginInfo; } public GrailsPluginInfo readPluginInfo(ClassNode classNode) throws CompilationFailedException { String className = classNode.getNameWithoutPackage(); if(className.endsWith("GrailsPlugin")) { visitContents(className, classNode); } return pluginInfo; } protected void visitContents(String className, final ClassNode classNode) { ClassCodeVisitorSupport visitor = new ClassCodeVisitorSupport() { @Override public void visitProperty(PropertyNode node) { String name = node.getName(); final Expression expr = node.getField().getInitialExpression(); if (expr != null) { Object value = null; if (expr instanceof ListExpression) { final List<String> list = new ArrayList<String>(); for (Expression i : ((ListExpression)expr).getExpressions()) { list.add(i.getText()); } value = list; } else if (expr instanceof MapExpression) { final Map<String, String> map = new LinkedHashMap<String, String>(); value = map; for (MapEntryExpression mee : ((MapExpression)expr).getMapEntryExpressions()) { map.put(mee.getKeyExpression().getText(), mee.getValueExpression().getText()); } } else { if(expr instanceof ConstantExpression) { value = expr.getText(); } } if(value != null) { pluginInfo.setProperty(name, value); super.visitProperty(node); } } } @Override protected SourceUnit getSourceUnit() { return classNode.getModule().getContext(); } }; classNode.visitContents(visitor); pluginInfo.setName(GrailsNameUtils.getPluginName(className + ".groovy")); } /** * Simple Javabean implementation of the GrailsPluginInfo interface. * * @author Graeme Rocher * @since 1.3 */ public class BasicGrailsPluginInfo implements GrailsPluginInfo { private String name; private String version; private Map<String,Object> attributes = new ConcurrentHashMap<String,Object>(); public BasicGrailsPluginInfo() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public void setProperty(String property, Object newValue) { attributes.put(property, newValue); } public Object getProperty(String property) { return attributes.get(property); } public String getFullName() { return name + '-' + version; } public Resource getDescriptor() { return null; } public Resource getPluginDir() { return null; } @SuppressWarnings({ "unchecked", "rawtypes" }) public Map getProperties() { Map props = new HashMap(); props.putAll(attributes); props.put(NAME, name); props.put(VERSION, version); return props; } } }