View Javadoc
1   package org.apache.maven.plugins.invoker;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import org.apache.maven.project.MavenProject;
28  import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
29  
30  /**
31   * A map-like source to interpolate expressions.
32   *
33   * @author Olivier Lamy
34   * @since 1.1
35   */
36  class CompositeMap
37      implements Map<String, Object>
38  {
39  
40      /**
41       * The Maven project from which to extract interpolated values, never <code>null</code>.
42       */
43      private MavenProject mavenProject;
44  
45      /**
46       * The set of additional properties from which to extract interpolated values, never <code>null</code>.
47       */
48      private Map<String, Object> properties;
49  
50      /**
51       * Flag indicating to escape XML special characters.
52       */
53      private final boolean escapeXml;
54  
55      /**
56       * Creates a new interpolation source backed by the specified Maven project and some user-specified properties.
57       *
58       * @param mavenProject The Maven project from which to extract interpolated values, must not be <code>null</code>.
59       * @param properties The set of additional properties from which to extract interpolated values, may be
60       *            <code>null</code>.
61       * @param escapeXml {@code true}, to escape any XML special characters; {@code false}, to not perform any escaping.
62       */
63      protected CompositeMap( MavenProject mavenProject, Map<String, Object> properties, boolean escapeXml )
64      {
65          if ( mavenProject == null )
66          {
67              throw new IllegalArgumentException( "no project specified" );
68          }
69          this.mavenProject = mavenProject;
70          this.properties = properties == null ? new HashMap<String, Object>() : properties;
71          this.escapeXml = escapeXml;
72      }
73  
74      /**
75       * {@inheritDoc}
76       *
77       * @see java.util.Map#clear()
78       */
79      public void clear()
80      {
81          // nothing here
82      }
83  
84      /**
85       * {@inheritDoc}
86       *
87       * @see java.util.Map#containsKey(java.lang.Object)
88       */
89      public boolean containsKey( Object key )
90      {
91          if ( !( key instanceof String ) )
92          {
93              return false;
94          }
95  
96          String expression = (String) key;
97          if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
98          {
99              try
100             {
101                 Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
102                 if ( evaluated != null )
103                 {
104                     return true;
105                 }
106             }
107             catch ( Exception e )
108             {
109                 // uhm do we have to throw a RuntimeException here ?
110             }
111         }
112 
113         return properties.containsKey( key ) || mavenProject.getProperties().containsKey( key );
114     }
115 
116     /**
117      * {@inheritDoc}
118      *
119      * @see java.util.Map#containsValue(java.lang.Object)
120      */
121     public boolean containsValue( Object value )
122     {
123         throw new UnsupportedOperationException();
124     }
125 
126     /**
127      * {@inheritDoc}
128      *
129      * @see java.util.Map#entrySet()
130      */
131     public Set<Entry<String, Object>> entrySet()
132     {
133         throw new UnsupportedOperationException();
134     }
135 
136     /**
137      * {@inheritDoc}
138      *
139      * @see java.util.Map#get(java.lang.Object)
140      */
141     public Object get( Object key )
142     {
143         if ( !( key instanceof String ) )
144         {
145             return null;
146         }
147 
148         Object value = null;
149         String expression = (String) key;
150         if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
151         {
152             try
153             {
154                 Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
155                 if ( evaluated != null )
156                 {
157                     value = evaluated;
158                 }
159             }
160             catch ( Exception e )
161             {
162                 // uhm do we have to throw a RuntimeException here ?
163             }
164         }
165 
166         if ( value == null )
167         {
168             value = properties.get( key );
169         }
170 
171         if ( value == null )
172         {
173             value = this.mavenProject.getProperties().get( key );
174         }
175 
176         if ( value != null && this.escapeXml )
177         {
178             value = value.toString().
179                 replaceAll( "\"", "&quot;" ).
180                 replaceAll( "<", "&lt;" ).
181                 replaceAll( ">", "&gt;" ).
182                 replaceAll( "&", "&amp;" );
183 
184         }
185 
186         return value;
187     }
188 
189     /**
190      * {@inheritDoc}
191      *
192      * @see java.util.Map#isEmpty()
193      */
194     public boolean isEmpty()
195     {
196         return this.mavenProject.getProperties().isEmpty() && this.properties.isEmpty();
197     }
198 
199     /**
200      * {@inheritDoc}
201      *
202      * @see java.util.Map#keySet()
203      */
204     public Set<String> keySet()
205     {
206         throw new UnsupportedOperationException();
207     }
208 
209     /**
210      * {@inheritDoc}
211      *
212      * @see java.util.Map#put(java.lang.Object, java.lang.Object)
213      */
214     public Object put( String key, Object value )
215     {
216         throw new UnsupportedOperationException();
217     }
218 
219     /**
220      * {@inheritDoc}
221      *
222      * @see java.util.Map#putAll(java.util.Map)
223      */
224     public void putAll( Map<? extends String, ? extends Object> t )
225     {
226         throw new UnsupportedOperationException();
227     }
228 
229     /**
230      * {@inheritDoc}
231      *
232      * @see java.util.Map#remove(java.lang.Object)
233      */
234     public Object remove( Object key )
235     {
236         throw new UnsupportedOperationException();
237     }
238 
239     /**
240      * {@inheritDoc}
241      *
242      * @see java.util.Map#size()
243      */
244     public int size()
245     {
246         throw new UnsupportedOperationException();
247     }
248 
249     /**
250      * {@inheritDoc}
251      *
252      * @see java.util.Map#values()
253      */
254     public Collection<Object> values()
255     {
256         throw new UnsupportedOperationException();
257     }
258 }