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