1 package com.atlassian.maven.plugins.amps.product;
2
3
4 import static org.apache.commons.io.FileUtils.copyDirectory;
5 import static org.apache.commons.lang.StringUtils.isNotBlank;
6
7 import java.io.File;
8 import java.io.IOException;
9 import java.io.UnsupportedEncodingException;
10 import java.net.InetAddress;
11 import java.net.URLEncoder;
12 import java.net.UnknownHostException;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.List;
16
17 import org.apache.commons.io.FileUtils;
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.maven.plugin.MojoExecutionException;
20 import org.apache.maven.plugin.logging.Log;
21 import org.apache.maven.project.MavenProject;
22
23 import com.atlassian.maven.plugins.amps.MavenContext;
24 import com.atlassian.maven.plugins.amps.MavenGoals;
25 import com.atlassian.maven.plugins.amps.Product;
26 import com.atlassian.maven.plugins.amps.ProductArtifact;
27 import com.atlassian.maven.plugins.amps.util.ConfigFileUtils;
28 import com.atlassian.maven.plugins.amps.util.ConfigFileUtils.Replacement;
29 import com.atlassian.maven.plugins.amps.util.ProjectUtils;
30 import com.atlassian.maven.plugins.amps.util.ZipUtils;
31 import com.google.common.collect.Lists;
32
33
34
35
36
37
38
39
40
41 public abstract class AmpsProductHandler implements ProductHandler
42 {
43
44 protected final MavenGoals goals;
45 protected final MavenProject project;
46 protected final MavenContext context;
47 protected final Log log;
48
49 protected AmpsProductHandler(MavenContext context, MavenGoals goals)
50 {
51 this.project = context.getProject();
52 this.context = context;
53 this.goals = goals;
54 this.log = context.getLog();
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public void createHomeZip(final File homeDirectory, final File targetZip, final Product product) throws MojoExecutionException
70 {
71 if (homeDirectory == null || !homeDirectory.exists())
72 {
73 String homePath = "null";
74 if (homeDirectory != null)
75 {
76 homePath = homeDirectory.getAbsolutePath();
77 }
78 context.getLog().info("home directory doesn't exist, skipping. [" + homePath + "]");
79 return;
80 }
81
82
83 try
84 {
85
86
87
88 final File appDir = getBaseDirectory(product);
89 final File tmpDir = new File(appDir, "tmp-resources");
90 final File homeSnapshot = new File(tmpDir, "generated-home");
91 final String entryBase = "generated-resources/" + product.getId() + "-home";
92
93 if (homeSnapshot.exists())
94 {
95 FileUtils.deleteDirectory(homeSnapshot);
96 }
97
98 homeSnapshot.mkdirs();
99 FileUtils.copyDirectory(homeDirectory, homeSnapshot, true);
100
101 cleanupProductHomeForZip(product, homeSnapshot);
102 ZipUtils.zipDir(targetZip, homeSnapshot, entryBase);
103 }
104 catch (IOException e)
105 {
106 throw new RuntimeException("Error zipping home directory", e);
107 }
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121 public void cleanupProductHomeForZip(Product product, File snapshotDir) throws MojoExecutionException, IOException
122 {
123 try {
124
125 FileUtils.deleteDirectory(new File(snapshotDir, "plugins"));
126 FileUtils.deleteDirectory(new File(snapshotDir, "bundled-plugins"));
127
128
129
130 if (this.getTestResourcesArtifact() != null)
131 {
132 String originalHomeZip = this.getTestResourcesArtifact().getArtifactId() + ".zip";
133 FileUtils.deleteQuietly(new File(snapshotDir, originalHomeZip));
134 }
135
136
137
138 List<Replacement> replacements = getReplacements(product);
139
140 Collections.sort(replacements, new Comparator<Replacement>(){
141 @Override
142 public int compare(Replacement replacement1, Replacement replacement2)
143 {
144
145 int length1 = replacement1.getValue().length();
146 int length2 = replacement2.getValue().length();
147 return length2 - length1;
148 }
149 });
150 List<File> files = getConfigFiles(product, snapshotDir);
151
152 ConfigFileUtils.replace(files, replacements, true, log);
153 }
154 catch (IOException ioe)
155 {
156 throw new MojoExecutionException("Could not delete home/plugins/ and /home/bundled-plugins/", ioe);
157 }
158 }
159
160 abstract protected ProductArtifact getTestResourcesArtifact();
161
162 protected File getProductHomeData(final Product ctx) throws MojoExecutionException
163 {
164 File productHomeZip = null;
165 String dataPath = ctx.getDataPath();
166
167
168 if (isNotBlank(dataPath))
169 {
170 File customHomeZip = new File(dataPath);
171
172 if (customHomeZip.exists())
173 {
174 return customHomeZip;
175 }
176 throw new MojoExecutionException("Unable to use custom test resources set by <dataPath>. File '" +
177 customHomeZip.getAbsolutePath() + "' does not exist");
178 }
179
180
181 ProductArtifact testResourcesArtifact = getTestResourcesArtifact();
182 if (productHomeZip == null && testResourcesArtifact != null)
183 {
184 ProductArtifact artifact = new ProductArtifact(
185 testResourcesArtifact.getGroupId(), testResourcesArtifact.getArtifactId(), ctx.getDataVersion());
186 productHomeZip = goals.copyHome(getBaseDirectory(ctx), artifact);
187 }
188
189 return productHomeZip;
190 }
191
192 protected void overrideAndPatchHomeDir(File homeDir, final Product ctx) throws MojoExecutionException
193 {
194 try
195 {
196 final File srcDir = new File(project.getBasedir(), "src/test/resources/" + ctx.getInstanceId() + "-home");
197 if (srcDir.exists() && homeDir.exists())
198 {
199 copyDirectory(srcDir, homeDir);
200 }
201 }
202 catch (IOException e)
203 {
204 throw new MojoExecutionException("Unable to override files using src/test/resources", e);
205 }
206 }
207
208
209
210
211
212
213
214 public List<ConfigFileUtils.Replacement> getReplacements(Product product)
215 {
216
217 List<Replacement> replacements = Lists.newArrayList();
218 String buildDirectory = project.getBuild().getDirectory();
219 String baseDirectory = getBaseDirectory(product).getAbsolutePath();
220 String homeDirectory = getHomeDirectory(product).getAbsolutePath();
221
222 replacements.add(new Replacement("%PROJECT_BUILD_DIR%", buildDirectory));
223 replacements.add(new Replacement("%PRODUCT_BASE_DIR%", baseDirectory));
224 replacements.add(new Replacement("%PRODUCT_HOME_DIR%", homeDirectory));
225
226
227 try {
228 replacements.add(new Replacement("%PROJECT_BUILD_DIR_URL_ENCODED%", URLEncoder.encode(propertiesEncode(buildDirectory), "UTF-8")));
229 replacements.add(new Replacement("%PRODUCT_BASE_DIR_URL_ENCODED%", URLEncoder.encode(propertiesEncode(baseDirectory), "UTF-8")));
230 replacements.add(new Replacement("%PRODUCT_HOME_DIR_URL_ENCODED%", URLEncoder.encode(propertiesEncode(homeDirectory), "UTF-8")));
231 }
232 catch (UnsupportedEncodingException badJvm)
233 {
234 throw new RuntimeException("UTF-8 should be supported on any JVM", badJvm);
235 }
236
237 replacements.add(Replacement.onlyWhenCreatingSnapshot("localhost", product.getServer()));
238
239 try
240 {
241 String localHostName = InetAddress.getLocalHost().getHostName();
242 replacements.add(new Replacement("%LOCAL_HOST_NAME%", localHostName));
243 }
244 catch (UnknownHostException e)
245 {
246
247
248 }
249
250 return replacements;
251 }
252
253
254
255
256 protected String propertiesEncode(String decoded)
257 {
258 if (decoded == null)
259 {
260 return null;
261 }
262 String replacement1 = decoded.replaceAll(":", "\\:");
263 String replacement2 = replacement1.replaceAll("=", "\\=");
264 return replacement2;
265 }
266
267 @Override
268 public List<File> getConfigFiles(Product product, File snapshotDir)
269 {
270 return Lists.newArrayList();
271 }
272
273 public File getBaseDirectory(Product ctx)
274 {
275 return ProjectUtils.createDirectory(new File(project.getBuild().getDirectory(), ctx.getInstanceId()));
276 }
277
278 public File getHomeDirectory(Product ctx)
279 {
280 if (StringUtils.isNotBlank(ctx.getDataHome()))
281 {
282 return new File(ctx.getDataHome());
283 }
284 return new File(getBaseDirectory(ctx), "home");
285 }
286
287 public File getSnapshotDirectory(Product product)
288 {
289 return getHomeDirectory(product);
290 }
291
292 protected File createHomeDirectory(Product ctx)
293 {
294 return ProjectUtils.createDirectory(getHomeDirectory(ctx));
295 }
296 }