KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > maven > project > interpolation > RegexBasedModelInterpolator


1 package org.apache.maven.project.interpolation;
2
3 /*
4  * Copyright 2001-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import org.apache.maven.model.Model;
20 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
21 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
22 import org.codehaus.plexus.logging.AbstractLogEnabled;
23 import org.codehaus.plexus.logging.Logger;
24 import org.codehaus.plexus.util.StringUtils;
25 import org.codehaus.plexus.util.cli.CommandLineUtils;
26 import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
27 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
28
29 import java.io.IOException JavaDoc;
30 import java.io.StringReader JavaDoc;
31 import java.io.StringWriter JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Properties JavaDoc;
34 import java.util.regex.Matcher JavaDoc;
35 import java.util.regex.Pattern JavaDoc;
36
37 /**
38  * Use a regular expression search to find and resolve expressions within the POM.
39  *
40  * @author jdcasey Created on Feb 3, 2005
41  * @version $Id: RegexBasedModelInterpolator.java 391974 2006-04-06 12:47:20Z jdcasey $
42  * @todo Consolidate this logic with the PluginParameterExpressionEvaluator, minus deprecations/bans.
43  */

44 public class RegexBasedModelInterpolator
45     extends AbstractLogEnabled
46     implements ModelInterpolator
47 {
48     private static final Pattern JavaDoc EXPRESSION_PATTERN = Pattern.compile( "\\$\\{(pom\\.|project\\.|env\\.)?([^}]+)\\}" );
49
50     private Properties JavaDoc envars;
51
52     public RegexBasedModelInterpolator( Properties JavaDoc envars )
53     {
54         this.envars = envars;
55     }
56
57     public RegexBasedModelInterpolator()
58         throws IOException JavaDoc
59     {
60         envars = CommandLineUtils.getSystemEnvVars();
61     }
62
63     public Model interpolate( Model model, Map JavaDoc context )
64         throws ModelInterpolationException
65     {
66         return interpolate( model, context, true );
67     }
68
69     /**
70      * Serialize the inbound Model instance to a StringWriter, perform the regex replacement to resolve
71      * POM expressions, then re-parse into the resolved Model instance.
72      * <br/>
73      * <b>NOTE:</b> This will result in a different instance of Model being returned!!!
74      *
75      * @param model The inbound Model instance, to serialize and reference for expression resolution
76      * @param context The other context map to be used during resolution
77      * @return The resolved instance of the inbound Model. This is a different instance!
78      */

79     public Model interpolate( Model model, Map JavaDoc context, boolean strict )
80         throws ModelInterpolationException
81     {
82         StringWriter JavaDoc sWriter = new StringWriter JavaDoc();
83
84         MavenXpp3Writer writer = new MavenXpp3Writer();
85         try
86         {
87             writer.write( sWriter, model );
88         }
89         catch ( IOException JavaDoc e )
90         {
91             throw new ModelInterpolationException( "Cannot serialize project model for interpolation.", e );
92         }
93
94         String JavaDoc serializedModel = sWriter.toString();
95         serializedModel = interpolateInternal( serializedModel, model, context );
96
97         StringReader JavaDoc sReader = new StringReader JavaDoc( serializedModel );
98
99         MavenXpp3Reader modelReader = new MavenXpp3Reader();
100         try
101         {
102             model = modelReader.read( sReader );
103         }
104         catch ( IOException JavaDoc e )
105         {
106             throw new ModelInterpolationException(
107                 "Cannot read project model from interpolating filter of serialized version.", e );
108         }
109         catch ( XmlPullParserException e )
110         {
111             throw new ModelInterpolationException(
112                 "Cannot read project model from interpolating filter of serialized version.", e );
113         }
114
115         return model;
116     }
117
118     private String JavaDoc interpolateInternal( String JavaDoc src, Model model, Map JavaDoc context )
119         throws ModelInterpolationException
120     {
121         String JavaDoc result = src;
122         Matcher JavaDoc matcher = EXPRESSION_PATTERN.matcher( result );
123         while ( matcher.find() )
124         {
125             String JavaDoc wholeExpr = matcher.group( 0 );
126             String JavaDoc realExpr = matcher.group( 2 );
127
128             Object JavaDoc value = context.get( realExpr );
129
130             if ( value == null )
131             {
132                 // This may look out of place, but its here for the MNG-2124/MNG-1927 fix described in the project builder
133
if ( context.containsKey( realExpr ) )
134                 {
135                     // It existed, but was null. Leave it alone.
136
continue;
137                 }
138
139                 value = model.getProperties().getProperty( realExpr );
140             }
141
142             if ( value == null )
143             {
144                 try
145                 {
146                     // NOTE: We've already trimmed off any leading expression parts like 'project.'
147
// or 'pom.', and now we have to ensure that the ReflectionValueExtractor
148
// doesn't try to do it again.
149
value = ReflectionValueExtractor.evaluate( realExpr, model, false );
150                 }
151                 catch ( Exception JavaDoc e )
152                 {
153                     Logger logger = getLogger();
154                     if ( logger != null )
155                     {
156                         logger.debug( "POM interpolation cannot proceed with expression: " + wholeExpr + ". Skipping...", e );
157                     }
158                 }
159             }
160
161             if ( value == null )
162             {
163                 value = envars.getProperty( realExpr );
164             }
165
166             // if the expression refers to itself, skip it.
167
if ( String.valueOf( value ).indexOf( wholeExpr ) > -1 )
168             {
169                 throw new ModelInterpolationException( wholeExpr, model.getId() + " references itself." );
170             }
171
172             if ( value != null )
173             {
174                 result = StringUtils.replace( result, wholeExpr, String.valueOf( value ) );
175                 // could use:
176
// result = matcher.replaceFirst( stringValue );
177
// but this could result in multiple lookups of stringValue, and replaceAll is not correct behaviour
178
matcher.reset( result );
179             }
180 /*
181         // This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
182         // timing of executing the interpolation
183
184             else
185             {
186                 throw new ModelInterpolationException(
187                     "Expression '" + wholeExpr + "' did not evaluate to anything in the model" );
188             }
189 */

190         }
191
192         return result;
193     }
194
195 }
Popular Tags