1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.core.NodeData;
40 import info.magnolia.cms.util.NodeDataUtil;
41 import info.magnolia.module.delta.AbstractRepositoryTask;
42 import info.magnolia.module.delta.Delta;
43 import info.magnolia.module.delta.DeltaBuilder;
44 import info.magnolia.module.delta.ModuleFilesExtraction;
45 import info.magnolia.module.delta.TaskExecutionException;
46 import info.magnolia.module.delta.Task;
47 import info.magnolia.module.delta.Condition;
48 import info.magnolia.module.model.ModuleDefinition;
49 import info.magnolia.module.model.Version;
50 import info.magnolia.module.model.VersionComparator;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import javax.jcr.RepositoryException;
55 import java.util.ArrayList;
56 import java.util.Collections;
57 import java.util.LinkedList;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.TreeMap;
61
62
63
64
65
66
67
68
69
70
71 public abstract class AbstractModuleVersionHandler implements ModuleVersionHandler {
72
73 protected Logger log = LoggerFactory.getLogger(getClass());
74
75 private final Map<Version, Delta> allDeltas;
76
77 public AbstractModuleVersionHandler() {
78 allDeltas = new TreeMap<Version, Delta>(new VersionComparator());
79 }
80
81
82
83
84
85 protected void register(Delta delta) {
86 final Version v = delta.getVersion();
87 if (allDeltas.containsKey(v)) {
88 throw new IllegalStateException("Version " + v + " was already registered in this ModuleVersionHandler.");
89 }
90 delta.getTasks().addAll(getDefaultUpdateTasks(v));
91 delta.getConditions().addAll(getDefaultUpdateConditions(v));
92 allDeltas.put(v, delta);
93 }
94
95 @Override
96 public Version getCurrentlyInstalled(InstallContext ctx) {
97 try {
98 log.debug("checking currently installed version of module [{}]", ctx.getCurrentModuleDefinition());
99
100
101 if (!ctx.hasModulesNode()) {
102 return null;
103 }
104 final Content moduleNode = ctx.getOrCreateCurrentModuleNode();
105 final NodeData versionProp = moduleNode.getNodeData("version");
106 if (!versionProp.isExist()) {
107 return null;
108 }
109
110 return Version.parseVersion(versionProp.getString());
111 } catch (RepositoryException e) {
112 throw new RuntimeException(e);
113 }
114 }
115
116 @Override
117 public List<Delta> getDeltas(InstallContext installContext, Version from) {
118 if (from == null) {
119 return Collections.singletonList(getInstall(installContext));
120 }
121
122 return getUpdateDeltas(installContext, from);
123 }
124
125 protected List<Delta> getUpdateDeltas(InstallContext installContext, Version from) {
126 final List<Delta> deltas = new LinkedList<Delta>();
127 for (Version v : allDeltas.keySet()) {
128 if (v.isStrictlyAfter(from)) {
129 deltas.add(allDeltas.get(v));
130 }
131 }
132
133
134 final Version toVersion = installContext.getCurrentModuleDefinition().getVersion();
135 if (toVersion.isStrictlyAfter(from) && !allDeltas.containsKey(toVersion)) {
136 deltas.add(getDefaultUpdate(installContext));
137 }
138 return deltas;
139 }
140
141
142
143
144 protected Delta getUpdate(InstallContext installContext) {
145 return getDefaultUpdate(installContext);
146 }
147
148
149
150
151
152 protected Delta getDefaultUpdate(InstallContext installContext) {
153 final Version toVersion = installContext.getCurrentModuleDefinition().getVersion();
154 final List<Task> defaultUpdateTasks = getDefaultUpdateTasks(toVersion);
155 final List<Condition> defaultUpdateConditions = getDefaultUpdateConditions(toVersion);
156 return DeltaBuilder.update(toVersion, "").addTasks(defaultUpdateTasks).addConditions(defaultUpdateConditions);
157 }
158
159 protected List<Task> getDefaultUpdateTasks(Version forVersion) {
160 final List<Task> defaultUpdates = new ArrayList<Task>(2);
161 defaultUpdates.add(new ModuleFilesExtraction());
162 defaultUpdates.add(new ModuleVersionUpdateTask(forVersion));
163 return defaultUpdates;
164 }
165
166 protected List<Condition> getDefaultUpdateConditions(Version forVersion) {
167 return Collections.emptyList();
168 }
169
170
171
172
173
174
175 protected Delta getInstall(InstallContext installContext) {
176 final List<Task> installTasks = new ArrayList<Task>();
177 installTasks.addAll(getBasicInstallTasks(installContext));
178 installTasks.addAll(getExtraInstallTasks(installContext));
179 installTasks.add(new ModuleVersionToLatestTask());
180 final List<Condition> conditions = getInstallConditions();
181 final Version version = installContext.getCurrentModuleDefinition().getVersion();
182 return DeltaBuilder.install(version, "").addTasks(installTasks).addConditions(conditions);
183 }
184
185 protected abstract List<Task> getBasicInstallTasks(InstallContext installContext);
186
187
188
189
190
191 protected List<Task> getExtraInstallTasks(InstallContext installContext) {
192 return Collections.emptyList();
193 }
194
195 protected List<Condition> getInstallConditions() {
196 return Collections.emptyList();
197 }
198
199 @Override
200 public Delta getStartupDelta(InstallContext installContext) {
201 final ModuleDefinition moduleDef = installContext.getCurrentModuleDefinition();
202 final List<Task> tasks = getStartupTasks(installContext);
203 return DeltaBuilder.startup(moduleDef, tasks);
204 }
205
206
207
208
209
210 protected List<Task> getStartupTasks(InstallContext installContext) {
211 return Collections.emptyList();
212 }
213
214
215
216
217
218
219 public class ModuleVersionToLatestTask extends AbstractRepositoryTask {
220 protected ModuleVersionToLatestTask() {
221 super("Version number", "Sets installed module version number.");
222 }
223
224 @Override
225 protected void doExecute(InstallContext ctx) throws RepositoryException, TaskExecutionException {
226
227 if (!ctx.hasModulesNode()) {
228 final HierarchyManager hm = ctx.getConfigHierarchyManager();
229 hm.createContent("/", ModuleManagerImpl.MODULES_NODE, ItemType.CONTENT.getSystemName());
230 }
231
232 final Content moduleNode = ctx.getOrCreateCurrentModuleNode();
233 final NodeData nodeData = NodeDataUtil.getOrCreate(moduleNode, "version");
234 nodeData.setValue(getVersion(ctx).toString());
235 }
236
237 protected Version getVersion(InstallContext ctx) {
238 return ctx.getCurrentModuleDefinition().getVersion();
239 }
240 }
241
242
243
244
245 public class ModuleVersionUpdateTask extends ModuleVersionToLatestTask {
246 private final Version toVersion;
247
248 protected ModuleVersionUpdateTask(Version toVersion) {
249 super();
250 this.toVersion = toVersion;
251 }
252
253 @Override
254 protected Version getVersion(InstallContext ctx) {
255 return toVersion;
256 }
257 }
258
259 }