1 package com.atlassian.plugin.osgi.factory.transform;
2
3 import com.atlassian.plugin.osgi.hostcomponents.HostComponentRegistration;
4 import com.atlassian.plugin.osgi.factory.transform.stage.*;
5 import org.apache.commons.lang.Validate;
6 import org.apache.log4j.Logger;
7
8 import java.io.*;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.zip.ZipEntry;
14 import java.util.zip.ZipInputStream;
15 import java.util.zip.ZipOutputStream;
16
17
18
19
20 public class DefaultPluginTransformer implements PluginTransformer
21 {
22 private static final Logger log = Logger.getLogger(DefaultPluginTransformer.class);
23
24 private final String pluginDescriptorPath;
25 private final List<TransformStage> stages;
26
27
28
29
30
31
32
33 public DefaultPluginTransformer(String pluginDescriptorPath)
34 {
35 this(pluginDescriptorPath, new ArrayList<TransformStage>()
36 {{
37 add(new AddBundleOverridesStage());
38 add(new ComponentImportSpringStage());
39 add(new ComponentSpringStage());
40 add(new HostComponentSpringStage());
41 add(new ModuleTypeSpringStage());
42 add(new GenerateManifestStage());
43 }});
44 }
45
46
47
48
49
50
51
52
53 public DefaultPluginTransformer(String pluginDescriptorPath, List<TransformStage> stages)
54 {
55 Validate.notNull(pluginDescriptorPath, "The plugin descriptor path is required");
56 Validate.notNull(stages, "A list of stages is required");
57 this.pluginDescriptorPath = pluginDescriptorPath;
58 this.stages = Collections.unmodifiableList(new ArrayList<TransformStage>(stages));
59 }
60
61
62
63
64
65
66
67
68
69 public File transform(File pluginJar, List<HostComponentRegistration> regs) throws PluginTransformationException
70 {
71 Validate.notNull(pluginJar, "The plugin jar is required");
72 Validate.notNull(regs, "The host component registrations are required");
73 TransformContext context = new TransformContext(regs, pluginJar, pluginDescriptorPath);
74 for (TransformStage stage : stages)
75 {
76 stage.execute(context);
77 }
78
79
80 try
81 {
82 if (log.isDebugEnabled())
83 {
84 StringBuilder sb = new StringBuilder();
85 sb.append("Overriding files in ").append(pluginJar.getName()).append(":\n");
86 for (Map.Entry<String, byte[]> entry : context.getFileOverrides().entrySet())
87 {
88 sb.append("==").append(entry.getKey()).append("==\n");
89 sb.append(new String(entry.getValue()));
90 }
91 log.debug(sb.toString());
92 }
93 return addFilesToExistingZip(pluginJar, context.getFileOverrides());
94 }
95 catch (IOException e)
96 {
97 throw new PluginTransformationException("Unable to add files to plugin jar");
98 }
99 }
100
101
102
103
104
105
106
107
108
109
110 static File addFilesToExistingZip(File zipFile,
111 Map<String, byte[]> files) throws IOException
112 {
113
114 File tempFile = File.createTempFile(zipFile.getName(), null);
115
116 byte[] buf = new byte[1024];
117
118 ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile));
119 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tempFile));
120
121 ZipEntry entry = zin.getNextEntry();
122 while (entry != null)
123 {
124 String name = entry.getName();
125 if (!files.containsKey(name))
126 {
127
128 out.putNextEntry(new ZipEntry(name));
129
130 int len;
131 while ((len = zin.read(buf)) > 0)
132 out.write(buf, 0, len);
133 }
134 entry = zin.getNextEntry();
135 }
136
137 zin.close();
138
139 for (Map.Entry<String, byte[]> fentry : files.entrySet())
140 {
141 InputStream in = new ByteArrayInputStream(fentry.getValue());
142
143 out.putNextEntry(new ZipEntry(fentry.getKey()));
144
145 int len;
146 while ((len = in.read(buf)) > 0)
147 {
148 out.write(buf, 0, len);
149 }
150
151 out.closeEntry();
152 in.close();
153 }
154
155 out.close();
156 return tempFile;
157 }
158
159
160 }