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 public Version getCurrentlyInstalled(InstallContext ctx) {
96 try {
97 log.debug("checking currently installed version of module [{}]", ctx.getCurrentModuleDefinition());
98
99
100 if (!ctx.hasModulesNode()) {
101 return null;
102 }
103 final Content moduleNode = ctx.getOrCreateCurrentModuleNode();
104 final NodeData versionProp = moduleNode.getNodeData("version");
105 if (!versionProp.isExist()) {
106 return null;
107 }
108
109 return Version.parseVersion(versionProp.getString());
110 } catch (RepositoryException e) {
111 throw new RuntimeException(e);
112 }
113 }
114
115 public List<Delta> getDeltas(InstallContext installContext, Version from) {
116 if (from == null) {
117 return Collections.singletonList(getInstall(installContext));
118 }
119
120 return getUpdateDeltas(installContext, from);
121 }
122
123 protected List<Delta> getUpdateDeltas(InstallContext installContext, Version from) {
124 final List<Delta> deltas = new LinkedList<Delta>();
125 for (Version v : allDeltas.keySet()) {
126 if (v.isStrictlyAfter(from)) {
127 deltas.add(allDeltas.get(v));
128 }
129 }
130
131
132 final Version toVersion = installContext.getCurrentModuleDefinition().getVersion();
133 if (toVersion.isStrictlyAfter(from) && !allDeltas.containsKey(toVersion)) {
134 deltas.add(getDefaultUpdate(installContext));
135 }
136 return deltas;
137 }
138
139
140
141
142 protected Delta getUpdate(InstallContext installContext) {
143 return getDefaultUpdate(installContext);
144 }
145
146
147
148
149
150 protected Delta getDefaultUpdate(InstallContext installContext) {
151 final Version toVersion = installContext.getCurrentModuleDefinition().getVersion();
152 final List<Task> defaultUpdateTasks = getDefaultUpdateTasks(toVersion);
153 final List<Condition> defaultUpdateConditions = getDefaultUpdateConditions(toVersion);
154 return DeltaBuilder.update(toVersion, "").addTasks(defaultUpdateTasks).addConditions(defaultUpdateConditions);
155 }
156
157 protected List<Task> getDefaultUpdateTasks(Version forVersion) {
158 final List<Task> defaultUpdates = new ArrayList<Task>(2);
159 defaultUpdates.add(new ModuleFilesExtraction());
160 defaultUpdates.add(new ModuleVersionUpdateTask(forVersion));
161 return defaultUpdates;
162 }
163
164 protected List<Condition> getDefaultUpdateConditions(Version forVersion) {
165 return Collections.emptyList();
166 }
167
168
169
170
171
172
173 protected Delta getInstall(InstallContext installContext) {
174 final List<Task> installTasks = new ArrayList<Task>();
175 installTasks.addAll(getBasicInstallTasks(installContext));
176 installTasks.addAll(getExtraInstallTasks(installContext));
177 installTasks.add(new ModuleVersionToLatestTask());
178 final List<Condition> conditions = getInstallConditions();
179 final Version version = installContext.getCurrentModuleDefinition().getVersion();
180 return DeltaBuilder.install(version, "").addTasks(installTasks).addConditions(conditions);
181 }
182
183 protected abstract List<Task> getBasicInstallTasks(InstallContext installContext);
184
185
186
187
188
189 protected List<Task> getExtraInstallTasks(InstallContext installContext) {
190 return Collections.emptyList();
191 }
192
193 protected List<Condition> getInstallConditions() {
194 return Collections.emptyList();
195 }
196
197 public Delta getStartupDelta(InstallContext installContext) {
198 final ModuleDefinition moduleDef = installContext.getCurrentModuleDefinition();
199 final List<Task> tasks = getStartupTasks(installContext);
200 return DeltaBuilder.startup(moduleDef, tasks);
201 }
202
203
204
205
206
207 protected List<Task> getStartupTasks(InstallContext installContext) {
208 return Collections.emptyList();
209 }
210
211
212
213
214
215
216 public class ModuleVersionToLatestTask extends AbstractRepositoryTask {
217 protected ModuleVersionToLatestTask() {
218 super("Version number", "Sets installed module version number.");
219 }
220
221 protected void doExecute(InstallContext ctx) throws RepositoryException, TaskExecutionException {
222
223 if (!ctx.hasModulesNode()) {
224 final HierarchyManager hm = ctx.getConfigHierarchyManager();
225 hm.createContent("/", ModuleManagerImpl.MODULES_NODE, ItemType.CONTENT.getSystemName());
226 }
227
228 final Content moduleNode = ctx.getOrCreateCurrentModuleNode();
229 final NodeData nodeData = NodeDataUtil.getOrCreate(moduleNode, "version");
230 nodeData.setValue(getVersion(ctx).toString());
231 }
232
233 protected Version getVersion(InstallContext ctx) {
234 return ctx.getCurrentModuleDefinition().getVersion();
235 }
236 }
237
238
239
240
241 public class ModuleVersionUpdateTask extends ModuleVersionToLatestTask {
242 private final Version toVersion;
243
244 protected ModuleVersionUpdateTask(Version toVersion) {
245 super();
246 this.toVersion = toVersion;
247 }
248
249 protected Version getVersion(InstallContext ctx) {
250 return toVersion;
251 }
252 }
253
254 }