1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.scriptbuilder;
20
21 import static com.google.common.base.Preconditions.checkNotNull;
22
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26
27 import org.jclouds.scriptbuilder.domain.OsFamily;
28 import org.jclouds.scriptbuilder.domain.ShellToken;
29 import org.jclouds.scriptbuilder.domain.Statement;
30 import org.jclouds.scriptbuilder.util.Utils;
31
32 import com.google.common.annotations.VisibleForTesting;
33 import com.google.common.base.Function;
34 import com.google.common.collect.ImmutableSet;
35 import com.google.common.collect.Iterables;
36 import com.google.common.collect.Lists;
37 import com.google.common.collect.Maps;
38
39
40
41
42
43
44 public class ScriptBuilder implements Statement {
45
46 @VisibleForTesting
47 List<Statement> statements = Lists.newArrayList();
48
49 @VisibleForTesting
50 Map<String, Map<String, String>> variableScopes = Maps.newLinkedHashMap();
51
52 @VisibleForTesting
53 List<String> variablesToUnset = Lists.newArrayList("path", "javaHome", "libraryPath");
54
55 public ScriptBuilder addStatement(Statement statement) {
56 statements.add(checkNotNull(statement, "statement"));
57 return this;
58 }
59
60
61
62
63 public ScriptBuilder unsetEnvironmentVariable(String name) {
64 variablesToUnset.add(checkNotNull(name, "name"));
65 return this;
66 }
67
68
69
70
71 public ScriptBuilder addEnvironmentVariableScope(String scopeName, Map<String, String> variables) {
72 variableScopes.put(checkNotNull(scopeName, "scopeName"), checkNotNull(variables, "variables"));
73 return this;
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88 @Override
89 public String render(OsFamily osFamily) {
90 Map<String, String> functions = Maps.newLinkedHashMap();
91 functions.put("abort", Utils.writeFunctionFromResource("abort", osFamily));
92
93 for (Entry<String, Map<String, String>> entry : variableScopes.entrySet()) {
94 functions.put(entry.getKey(), Utils.writeFunction(entry.getKey(), Utils.writeVariableExporters(entry
95 .getValue())));
96 }
97 final Map<String, String> tokenValueMap = ShellToken.tokenValueMap(osFamily);
98 StringBuilder builder = new StringBuilder();
99 builder.append(ShellToken.BEGIN_SCRIPT.to(osFamily));
100 builder.append(Utils.writeUnsetVariables(Lists.newArrayList(Iterables.transform(variablesToUnset,
101 new Function<String, String>() {
102 @Override
103 public String apply(String from) {
104 if (tokenValueMap.containsKey(from + "Variable"))
105 return Utils.FUNCTION_UPPER_UNDERSCORE_TO_LOWER_CAMEL.apply(tokenValueMap
106 .get(from + "Variable"));
107 return from;
108 }
109
110 })), osFamily));
111 resolveFunctionDependencies(functions, osFamily);
112 if (functions.size() > 0) {
113 builder.append(ShellToken.BEGIN_FUNCTIONS.to(osFamily));
114 for (String function : functions.values()) {
115 builder.append(Utils.replaceTokens(function, tokenValueMap));
116 }
117 builder.append(ShellToken.END_FUNCTIONS.to(osFamily));
118 }
119 builder.append(Utils.writeZeroPath(osFamily));
120 StringBuilder statementBuilder = new StringBuilder();
121 for (Statement statement : statements) {
122 statementBuilder.append(statement.render(osFamily));
123 }
124 builder.append(statementBuilder.toString().replaceAll(ShellToken.RETURN.to(osFamily),
125 ShellToken.EXIT.to(osFamily)));
126 builder.append(ShellToken.END_SCRIPT.to(osFamily));
127 return builder.toString();
128 }
129
130 @VisibleForTesting
131 void resolveFunctionDependencies(Map<String, String> functions, final OsFamily osFamily) {
132 Iterable<String> dependentFunctions = Iterables.concat(Iterables.transform(statements,
133 new Function<Statement, Iterable<String>>() {
134 @Override
135 public Iterable<String> apply(Statement from) {
136 return from.functionDependencies(osFamily);
137 }
138 }));
139 List<String> unresolvedFunctions = Lists.newArrayList(dependentFunctions);
140 Iterables.removeAll(unresolvedFunctions, functions.keySet());
141 for (String functionName : unresolvedFunctions) {
142 functions.put(functionName, Utils.writeFunctionFromResource(functionName, osFamily));
143 }
144 }
145
146 @Override
147 public Iterable<String> functionDependencies(OsFamily family) {
148 return ImmutableSet.<String> of();
149 }
150 }