View Javadoc

1   package org.abstracthorizon.extend.repository.maven;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   import java.lang.reflect.Modifier;
6   import java.util.Collection;
7   import java.util.HashMap;
8   import java.util.Map;
9   
10  public class SubstitutionTraverser {
11  
12      protected static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
13      
14      protected static final Class<?>[] STRING_CLASS_ARRAY = new Class[]{String.class};
15      
16      protected static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
17      
18      @SuppressWarnings("unchecked")
19      public static void substitute(Object object, Map<String, String> substitutions) {
20  
21          Class<?> cls = object.getClass();
22          Method[] methods = cls.getMethods();
23          for (Method m : methods) {
24              if (!Modifier.isStatic(m.getModifiers())) {
25                  String name = m.getName();
26                  if (!name.equals("getClass") && name.startsWith("get") && (name.length() > 3)) {
27                      Class<?> returnType = m.getReturnType();
28                      if (returnType.equals(String.class)) {
29                          try {
30                              String value = (String)m.invoke(object, EMPTY_OBJECT_ARRAY);
31                              if ((value != null) && (value.indexOf("${") >= 0)) {
32                                  String newValue = substitute(value, substitutions);
33                                  Method writeBackMethod = cls.getMethod("s" + name.substring(1), STRING_CLASS_ARRAY);
34                                  writeBackMethod.invoke(object, new Object[]{newValue});
35                              }
36                          } catch (IllegalArgumentException ignore) {
37                          } catch (IllegalAccessException ignore) {
38                          } catch (InvocationTargetException ignore) {
39                          } catch (SecurityException ignore) {
40                          } catch (NoSuchMethodException ignore) {
41                          }
42                      } else if (!returnType.isPrimitive()) {
43                          try {
44                              Object obj = m.invoke(object, EMPTY_OBJECT_ARRAY);
45                              if (obj != null) {
46                                  if (obj instanceof Collection) {
47                                      for (Object o : (Collection)obj) {
48                                          substitute(o, substitutions);
49                                      }
50                                  } else if (obj.getClass().isArray()) {
51                                      for (Object o : (Object[])obj) {
52                                          substitute(o, substitutions);
53                                      }
54                                  } else {
55                                      substitute(obj, substitutions);
56                                  }
57                              }
58                          } catch (IllegalArgumentException ignore) {
59                          } catch (IllegalAccessException ignore) {
60                          } catch (InvocationTargetException ignore) {
61                          }
62                      }
63                  }
64              }
65          }
66      }
67      
68      public static String substitute(String value, Map<String, String> substitutions) {
69          int len = value.length();
70          StringBuffer buf = new StringBuffer(len);
71          int i = 0;
72          int ptr = 0;
73          int state = 0;
74          while (i < len) {
75              char c = value.charAt(i);
76              if (state == 0) {
77                  if (c == '$') {
78                      state = 1;
79                  }
80              } else if (state == 1) {
81                  if (c == '{') {
82                      if (i > 1) {
83                          buf.append(value.substring(ptr, i - 1));
84                      }
85                      ptr = i + 1;
86                      state = 2;
87                  } else {
88                      state = 0;
89                  }
90              } else if (state == 2) {
91                  if (c == '}') {
92                      String key = value.substring(ptr, i);
93                      String sub = substitutions.get(key);
94                      if (sub != null) {
95                          buf.append(sub);
96                      } else {
97                          buf.append("${").append(key).append('}');
98                      }
99                      ptr = i + 1;
100                     state = 0;
101                 }
102             }
103             i++;
104         }
105         if (ptr != i) {
106             if (state == 2) {
107                 buf.append("${");
108             }
109             buf.append(value.substring(ptr));
110         }
111         return buf.toString();
112     }
113     
114     public static void main(String[] args) throws Exception {
115         Map<String, String> map = new HashMap<String, String>();
116         map.put("pom.version", "0.4.0");
117         test("${pom.version}x", map);
118         test("y${pom.version}x", map);
119         test("y${pom.version}", map);
120         test("y${pom.version", map);
121         test("pom.version}", map);
122         test("pom.version", map);
123         test("y${pom.version}asd${some}", map);
124 
125         test("${pom.versionx}x", map);
126         test("y${pom.versionx}x", map);
127         test("y${pom.versionx}", map);
128 //        substitute(new SubstitutionTraverser(), null);
129     }
130 
131     public static void test(String value, Map<String, String> map) {
132         System.out.println(value + " = '" + substitute(value, map) + "'");
133     }
134 }