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( "\"", """ ).
181 replaceAll( "<", "<" ).
182 replaceAll( ">", ">" ).
183 replaceAll( "&", "&" );
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 }