You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ResolvePropertyMap.java 5.9 kB

11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.property;
  19. import java.util.Collection;
  20. import java.util.HashSet;
  21. import java.util.Map;
  22. import java.util.Set;
  23. import org.apache.tools.ant.BuildException;
  24. import org.apache.tools.ant.Project;
  25. /**
  26. * Class to resolve properties in a map. This class is explicitly not threadsafe.
  27. * @since Ant 1.8.0
  28. */
  29. public class ResolvePropertyMap implements GetProperty {
  30. private final Set<String> seen = new HashSet<>();
  31. private final ParseProperties parseProperties;
  32. private final GetProperty master;
  33. private Map<String, Object> map;
  34. private String prefix;
  35. // whether properties of the value side of the map should be
  36. // expanded
  37. private boolean prefixValues = false;
  38. // whether the current getProperty call is expanding the key side
  39. // of the map
  40. private boolean expandingLHS = true;
  41. /**
  42. * Constructor with a master getproperty and a collection of expanders.
  43. * @param project the current ant project.
  44. * @param master the master property holder (usually PropertyHelper)
  45. * @param expanders a collection of expanders (usually from PropertyHelper).
  46. */
  47. public ResolvePropertyMap(Project project, GetProperty master, Collection<PropertyExpander> expanders) {
  48. this.master = master;
  49. this.parseProperties = new ParseProperties(project, expanders, this);
  50. }
  51. /**
  52. * Returns the value of a property if it is set.
  53. * @param name name of the property.
  54. * @return the property value, or null for no match or for name being null.
  55. */
  56. @Override
  57. public Object getProperty(String name) {
  58. if (seen.contains(name)) {
  59. throw new BuildException("Property %s was circularly defined.",
  60. name);
  61. }
  62. try {
  63. // If the property we are looking up is a key in the map
  64. // (first call into this method from resolveAllProperties)
  65. // or we've been asked to prefix the value side (later
  66. // recursive calls via the GetProperty interface) the
  67. // prefix must be prepended when looking up the property
  68. // outside of the map.
  69. String fullKey = name;
  70. if (prefix != null && (expandingLHS || prefixValues)) {
  71. fullKey = prefix + name;
  72. }
  73. Object masterValue = master.getProperty(fullKey);
  74. if (masterValue != null) {
  75. // If the property already has a value outside of the
  76. // map, use that value to enforce property
  77. // immutability.
  78. return masterValue;
  79. }
  80. seen.add(name);
  81. String recursiveCallKey = name;
  82. if (prefix != null && !expandingLHS && !prefixValues) {
  83. // only look up nonprefixed properties inside the map
  84. // if prefixValues is true or we are expanding the key
  85. // itself
  86. recursiveCallKey = prefix + name;
  87. }
  88. expandingLHS = false;
  89. // will recurse into this method for each property
  90. // reference found in the map's value
  91. return parseProperties.parseProperties((String) map.get(recursiveCallKey));
  92. } finally {
  93. seen.remove(name);
  94. }
  95. }
  96. /**
  97. * The action method - resolves all the properties in a map.
  98. * @param map the map to resolve properties in.
  99. * @deprecated since Ant 1.8.2, use the three-arg method instead.
  100. */
  101. @Deprecated
  102. public void resolveAllProperties(Map<String, Object> map) {
  103. resolveAllProperties(map, null, false);
  104. }
  105. /**
  106. * The action method - resolves all the properties in a map.
  107. * @param map the map to resolve properties in.
  108. * @param prefix the prefix the properties defined inside the map
  109. * will finally receive - may be null.
  110. * @deprecated since Ant 1.8.2, use the three-arg method instead.
  111. */
  112. @Deprecated
  113. public void resolveAllProperties(Map<String, Object> map, String prefix) {
  114. resolveAllProperties(map, null, false);
  115. }
  116. /**
  117. * The action method - resolves all the properties in a map.
  118. * @param map the map to resolve properties in.
  119. * @param prefix the prefix the properties defined inside the map
  120. * will finally receive - may be null.
  121. * @param prefixValues - whether the prefix will be applied
  122. * to properties on the value side of the map as well.
  123. */
  124. public void resolveAllProperties(Map<String, Object> map, String prefix,
  125. boolean prefixValues) {
  126. // The map, prefix and prefixValues flag get used in the
  127. // getProperty callback
  128. this.map = map;
  129. this.prefix = prefix;
  130. this.prefixValues = prefixValues;
  131. for (String key : map.keySet()) {
  132. expandingLHS = true;
  133. Object result = getProperty(key);
  134. String value = result == null ? "" : result.toString();
  135. map.put(key, value);
  136. }
  137. }
  138. }