001 /* 002 * Copyright (C) 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.codehaus.gmaven.plugin.execute; 018 019 import org.apache.maven.execution.MavenSession; 020 import org.apache.maven.project.MavenProject; 021 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; 022 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; 023 import org.slf4j.Logger; 024 import org.slf4j.LoggerFactory; 025 026 import java.util.ArrayList; 027 import java.util.Collections; 028 import java.util.Iterator; 029 import java.util.List; 030 import java.util.Map; 031 import java.util.Properties; 032 033 /** 034 * Provides property resolution access to Groovy executions. 035 * 036 * @version $Id: GroovyMavenProjectAdapter.java 110 2010-08-06 19:46:53Z user57 $ 037 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> 038 */ 039 public class GroovyMavenProjectAdapter 040 extends MavenProjectDelegateAdapter 041 { 042 private final MavenSession session; 043 044 private final Map properties; 045 046 private final Map defaults; 047 048 private Properties props; 049 050 public GroovyMavenProjectAdapter(final MavenProject project, final MavenSession session, final Map properties, final Map defaults) { 051 super(project); 052 053 this.session = session; 054 this.properties = properties; 055 this.defaults = defaults; 056 } 057 058 public synchronized Properties getProperties() { 059 // Lazily construct a custom properties class to handle resolving properties as we want them 060 if (props == null) { 061 props = new EvaluatingProperties(); 062 } 063 064 return props; 065 } 066 067 /** 068 * Custom properties handling to resolve for Groovy executions. 069 */ 070 private class EvaluatingProperties 071 extends Properties 072 { 073 private final Logger log = LoggerFactory.getLogger(getClass()); 074 075 private final ExpressionEvaluator evaluator = new ExpressionEvaluatorImpl(session, GroovyMavenProjectAdapter.this); 076 077 public EvaluatingProperties() { 078 // Populate the base properties from the original model properties (so iter-based operations work as expected) 079 putAll(getModel().getProperties()); 080 081 // Add custom execution properties 082 if (properties != null) { 083 putAll(properties); 084 } 085 086 if (log.isDebugEnabled() && props != null && !props.isEmpty()) { 087 log.debug("Properties: "); 088 089 List keys = new ArrayList(); 090 keys.addAll(props.keySet()); 091 092 Collections.sort(keys); 093 094 for (Iterator iter = keys.iterator(); iter.hasNext();) { 095 String name = (String)iter.next(); 096 String value = props.getProperty(name); 097 098 log.debug(" {} -> {}", name, value); 099 } 100 } 101 } 102 103 // 104 // NOTE: lookup() and get() are marked as public intentionally... as they could be potentially useful by some 105 // advanced scripts which need richer access to properties. Though, I think Groovy's reflector muck 106 // can actually invoke the privates just as well. 107 // 108 109 public Object lookup(final Object key) { 110 // First try execution properties, should include system 111 Object value = session.getExecutionProperties().get(key); 112 113 // Else try ourselves 114 if (value == null) { 115 value = super.get(key); 116 } 117 118 // Then try defaults (from adapter, not from properties, which is not used) 119 if (value == null && GroovyMavenProjectAdapter.this.defaults != null) { 120 value = GroovyMavenProjectAdapter.this.defaults.get(key); 121 } 122 123 return value; 124 } 125 126 public Object get(final Object key, final boolean resolve) { 127 Object value = lookup(key); 128 129 // If the value is a string, evaluate it to get expressions to expand 130 if (resolve && value instanceof String) { 131 try { 132 value = evaluator.evaluate((String)value); 133 } 134 catch (ExpressionEvaluationException e) { 135 // If something bad happens just puke it up 136 throw new RuntimeException(e); 137 } 138 } 139 140 log.trace("Getting value: {} = {}", key, value); 141 142 return value; 143 } 144 145 public Object get(final Object key) { 146 return get(key, true); 147 } 148 149 public String getProperty(final String name) { 150 // We have to override getProperty() as the default impl gets the value from super.get() instead of get() 151 Object value = get(name); 152 153 log.trace("Getting property: {} = {}", name, value); 154 155 return value != null ? String.valueOf(value) : null; 156 } 157 158 public Object put(final Object key, final Object value) { 159 log.trace("Putting value: {} = {}", key, value); 160 161 // Have to set in the original to preserve between executions 162 getDelegate().getProperties().put(key, value); 163 164 // But need to update our self so resolution in the same execution works too 165 return super.put(key, value); 166 } 167 } 168 }