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   * @version $Id: CompositeMap.java 1784076 2017-02-23 00:35:39Z schulte $
36   */
37  class CompositeMap
38      implements Map<String, Object>
39  {
40  
41      /**
42       * The Maven project from which to extract interpolated values, never <code>null</code>.
43       */
44      private MavenProject mavenProject;
45  
46      /**
47       * The set of additional properties from which to extract interpolated values, never <code>null</code>.
48       */
49      private Map<String, Object> properties;
50  
51      /**
52       * Flag indicating to escape XML special characters.
53       */
54      private final boolean escapeXml;
55  
56      /**
57       * Creates a new interpolation source backed by the specified Maven project and some user-specified properties.
58       *
59       * @param mavenProject The Maven project from which to extract interpolated values, must not be <code>null</code>.
60       * @param properties The set of additional properties from which to extract interpolated values, may be
61       *            <code>null</code>.
62       * @param escapeXml {@code true}, to escape any XML special characters; {@code false}, to not perform any escaping.
63       */
64      protected CompositeMap( MavenProject mavenProject, Map<String, Object> properties, boolean escapeXml )
65      {
66          if ( mavenProject == null )
67          {
68              throw new IllegalArgumentException( "no project specified" );
69          }
70          this.mavenProject = mavenProject;
71          this.properties = properties == null ? new HashMap<String, Object>() : properties;
72          this.escapeXml = escapeXml;
73      }
74  
75      /**
76       * {@inheritDoc}
77       *
78       * @see java.util.Map#clear()
79       */
80      public void clear()
81      {
82          // nothing here
83      }
84  
85      /**
86       * {@inheritDoc}
87       *
88       * @see java.util.Map#containsKey(java.lang.Object)
89       */
90      public boolean containsKey( Object key )
91      {
92          if ( !( key instanceof String ) )
93          {
94              return false;
95          }
96  
97          String expression = (String) key;
98          if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
99          {
100             try
101             {
102                 Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
103                 if ( evaluated != null )
104                 {
105                     return true;
106                 }
107             }
108             catch ( Exception e )
109             {
110                 // uhm do we have to throw a RuntimeException here ?
111             }
112         }
113 
114         return properties.containsKey( key ) || mavenProject.getProperties().containsKey( key );
115     }
116 
117     /**
118      * {@inheritDoc}
119      *
120      * @see java.util.Map#containsValue(java.lang.Object)
121      */
122     public boolean containsValue( Object value )
123     {
124         throw new UnsupportedOperationException();
125     }
126 
127     /**
128      * {@inheritDoc}
129      *
130      * @see java.util.Map#entrySet()
131      */
132     public Set<Entry<String, Object>> entrySet()
133     {
134         throw new UnsupportedOperationException();
135     }
136 
137     /**
138      * {@inheritDoc}
139      *
140      * @see java.util.Map#get(java.lang.Object)
141      */
142     public Object get( Object key )
143     {
144         if ( !( key instanceof String ) )
145         {
146             return null;
147         }
148 
149         Object value = null;
150         String expression = (String) key;
151         if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
152         {
153             try
154             {
155                 Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
156                 if ( evaluated != null )
157                 {
158                     value = evaluated;
159                 }
160             }
161             catch ( Exception e )
162             {
163                 // uhm do we have to throw a RuntimeException here ?
164             }
165         }
166 
167         if ( value == null )
168         {
169             value = properties.get( key );
170         }
171 
172         if ( value == null )
173         {
174             value = this.mavenProject.getProperties().get( key );
175         }
176 
177         if ( value != null && this.escapeXml )
178         {
179             value = value.toString().
180                 replaceAll( "\"", "&quot;" ).
181                 replaceAll( "<", "&lt;" ).
182                 replaceAll( ">", "&gt;" ).
183                 replaceAll( "&", "&amp;" );
184 
185         }
186 
187         return value;
188     }
189 
190     /**
191      * {@inheritDoc}
192      *
193      * @see java.util.Map#isEmpty()
194      */
195     public boolean isEmpty()
196     {
197         return this.mavenProject.getProperties().isEmpty() && this.properties.isEmpty();
198     }
199 
200     /**
201      * {@inheritDoc}
202      *
203      * @see java.util.Map#keySet()
204      */
205     public Set<String> keySet()
206     {
207         throw new UnsupportedOperationException();
208     }
209 
210     /**
211      * {@inheritDoc}
212      *
213      * @see java.util.Map#put(java.lang.Object, java.lang.Object)
214      */
215     public Object put( String key, Object value )
216     {
217         throw new UnsupportedOperationException();
218     }
219 
220     /**
221      * {@inheritDoc}
222      *
223      * @see java.util.Map#putAll(java.util.Map)
224      */
225     public void putAll( Map<? extends String, ? extends Object> t )
226     {
227         throw new UnsupportedOperationException();
228     }
229 
230     /**
231      * {@inheritDoc}
232      *
233      * @see java.util.Map#remove(java.lang.Object)
234      */
235     public Object remove( Object key )
236     {
237         throw new UnsupportedOperationException();
238     }
239 
240     /**
241      * {@inheritDoc}
242      *
243      * @see java.util.Map#size()
244      */
245     public int size()
246     {
247         throw new UnsupportedOperationException();
248     }
249 
250     /**
251      * {@inheritDoc}
252      *
253      * @see java.util.Map#values()
254      */
255     public Collection<Object> values()
256     {
257         throw new UnsupportedOperationException();
258     }
259 }