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.cache.setup;
35
36 import info.magnolia.context.MgnlContext;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.module.DefaultModuleVersionHandler;
39 import info.magnolia.module.InstallContext;
40 import info.magnolia.module.cache.AbstractCacheModule;
41 import info.magnolia.module.delta.AbstractRepositoryTask;
42 import info.magnolia.module.delta.ArrayDelegateTask;
43 import info.magnolia.module.delta.BootstrapSingleModuleResource;
44 import info.magnolia.module.delta.BootstrapSingleResource;
45 import info.magnolia.module.delta.CheckAndModifyPropertyValueTask;
46 import info.magnolia.module.delta.CheckOrCreatePropertyTask;
47 import info.magnolia.module.delta.DeltaBuilder;
48 import info.magnolia.module.delta.FilterOrderingTask;
49 import info.magnolia.module.delta.HasPropertyDelegateTask;
50 import info.magnolia.module.delta.MoveNodeTask;
51 import info.magnolia.module.delta.NodeExistsDelegateTask;
52 import info.magnolia.module.delta.OrderNodeToFirstPositionTask;
53 import info.magnolia.module.delta.PartialBootstrapTask;
54 import info.magnolia.module.delta.RemoveNodeTask;
55 import info.magnolia.module.delta.RemoveNodeWoChildren;
56 import info.magnolia.module.delta.RemoveNodesTask;
57 import info.magnolia.module.delta.RemovePropertyTask;
58 import info.magnolia.module.delta.RenameNodeTask;
59 import info.magnolia.module.delta.RenamePropertyTask;
60 import info.magnolia.module.delta.SetPropertyTask;
61 import info.magnolia.module.delta.Task;
62 import info.magnolia.module.delta.TaskExecutionException;
63 import info.magnolia.repository.RepositoryConstants;
64 import info.magnolia.voting.voters.URIStartsWithVoter;
65
66 import java.util.ArrayList;
67 import java.util.Arrays;
68 import java.util.List;
69
70 import javax.jcr.Node;
71 import javax.jcr.RepositoryException;
72 import javax.jcr.Session;
73
74
75
76
77 public class CacheModuleVersionHandler extends DefaultModuleVersionHandler {
78
79 protected static final String OBSOLETE_COMPRESSIBLE_CONFIGURATION_PATH = "modules/cache/config/configurations/default/executors/store/cacheContent/compressible";
80 public static final String CONFIGURATION_PATH = "modules/cache/config/contentCaching/";
81 protected static final String OBSOLETE_DEFAULT_CONFIGURATION_PATH = "/modules/cache/config/configurations/default/";
82 protected static final String BROWSER_CACHE_POLICIES_CONTENT_TYPE_ALLOWED = "/modules/cache/config/contentCaching/defaultPageCache/browserCachePolicy/policies/resources/voters/contentType/allowed";
83
84 private final FilterOrderingTask placeGzipFilter = new FilterOrderingTask("gzip", new String[]{"context", "multipartRequest"}, new String[]{"activation", "publishing"});
85 private final FilterOrderingTask placeCacheFilter = new FilterOrderingTask("cache", new String[]{"gzip", "range", "i18n"});
86
87 private final Task addUidlCachePolicy = new AbstractRepositoryTask("Add uidl cache policy voter", "") {
88 final String path = "/modules/cache/config/configurations/default/cachePolicy/voters/deny";
89
90 @Override
91 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
92 Session session = MgnlContext.getJCRSession(RepositoryConstants.CONFIG);
93 if (session.nodeExists(path) && !session.nodeExists(path + "/uidl")) {
94 Node uidlNode = session.getNode(path).addNode("uidl", NodeTypes.ContentNode.NAME);
95 uidlNode.setProperty("class", URIStartsWithVoter.class.getName());
96 uidlNode.setProperty("enabled", "true");
97 uidlNode.setProperty("level", "2");
98 uidlNode.setProperty("pattern", "/.magnolia/admincentral/UIDL");
99 }
100 }
101 };
102
103 public CacheModuleVersionHandler() {
104 register(DeltaBuilder.checkPrecondition("4.4.6", "4.5"));
105
106 register(DeltaBuilder.update("4.5", "")
107 .addTask(placeGzipFilter)
108 .addTask(placeCacheFilter)
109 );
110
111 register(DeltaBuilder.update("5.1.1", "")
112 .addTask(new RemovePropertyTask("Remove hardcoded label", "Remove hardcoded label of Cache tools app", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/cacheTools", "label"))
113 .addTask(new RemovePropertyTask("Remove hardcoded icon", "Remove hardcoded icon of Cache tools app", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/cacheTools", "icon")));
114
115 register(DeltaBuilder.update("5.2", "")
116 .addTask(addUidlCachePolicy)
117 );
118
119 register(DeltaBuilder.update("5.4", "")
120
121 .addTask(new ArrayDelegateTask("Remove deprecated configuration",
122 new RemoveNodeTask("Remove obsolete compressible configuration.", "/" + OBSOLETE_COMPRESSIBLE_CONFIGURATION_PATH),
123 new MoveNodeTask("", OBSOLETE_DEFAULT_CONFIGURATION_PATH + "cachePolicy/voters", OBSOLETE_DEFAULT_CONFIGURATION_PATH + "cachePolicy/shouldBypassVoters", false),
124 new RemoveNodesTask("Remove deprecated cacheable voters",
125 RepositoryConstants.CONFIG, Arrays.asList(OBSOLETE_DEFAULT_CONFIGURATION_PATH + "executors/store/cacheContent/isCacheableVoters"), false)
126 ))
127
128 .addTask(new ArrayDelegateTask("Renaming of 'configurations' to 'contentCaching'",
129 String.format("Renames the 'configurations' nodes of the cache module to 'contentCaching'. Also renames the 'cacheConfigurationName' property of the cache filter to '%s'.", AbstractCacheModule.DEFAULT_CACHE_CONFIG),
130 new RenameNodeTask("", RepositoryConstants.CONFIG, "/modules/cache/config", "configurations", "contentCaching", false),
131 new RenameNodeTask("", RepositoryConstants.CONFIG, "/modules/cache/config/contentCaching", "default", "defaultPageCache", false),
132
133 new RenamePropertyTask("", RepositoryConstants.CONFIG, "/server/filters/cache", "cacheConfigurationName", AbstractCacheModule.DEFAULT_CACHE_CONFIG, false),
134 new CheckAndModifyPropertyValueTask("", "", RepositoryConstants.CONFIG, "/server/filters/cache", AbstractCacheModule.DEFAULT_CACHE_CONFIG, "default", "defaultPageCache")
135
136 ))
137
138 .addTask(new ArrayDelegateTask("Bootstrap new configuration",
139 new BootstrapSingleResource("Bootstrap voters for TTL", "Bootstrap voters for Time To Live", "/mgnl-bootstrap/cache/config.modules.cache.config.contentCaching.defaultPageCache.cachePolicy.ttlVoters.xml"),
140 new PartialBootstrapTask("Rebootstrap new default flush cache policy configuration",
141 "/mgnl-bootstrap/cache/config.modules.cache.config.contentCaching.defaultPageCache.xml", "defaultPageCache/flushPolicy/policies/flushAll"),
142 new PartialBootstrapTask("Rebootstrap new uuid-key-mapping flush cache policy configuration",
143 "/mgnl-bootstrap/cache/config.modules.cache.config.contentCaching.uuid-key-mapping.xml", "uuid-key-mapping/flushPolicy/policies/flushAll")
144 ))
145
146 .addTask(new NodeExistsDelegateTask("Remove old cache tools app", "/modules/ui-admincentral/apps/cacheTools",
147 new RemoveNodeTask("", "/modules/ui-admincentral/apps/cacheTools")))
148 .addTask(new NodeExistsDelegateTask("Remove cache tools page", "/modules/cache/pages/cachePage",
149 new RemoveNodeTask("", "/modules/cache/pages/cachePage")))
150 .addTask(new RemoveNodeWoChildren("Remove pages node if there are no pages registered.", "/modules/cache/pages"))
151 .addTask(new RemoveVirtualUriMappingTask())
152 .addTask(new CheckAndModifyPropertyValueTask("Browser cache policy for far-future caching", "Fixes pattern for far-future browser cache policy.", RepositoryConstants.CONFIG, "/modules/cache/config/contentCaching/defaultPageCache/browserCachePolicy/policies/farFuture/voters/dotCacheExtension", "pattern", ".*\\.cache\\.[^\\.]*", ".*[~.]cache\\.[^\\.]*"))
153 );
154
155 register(DeltaBuilder.update("5.4.1", "")
156 .addTask(new MigrateCacheFilterConfigurationTask())
157 );
158 register(DeltaBuilder.update("5.5.2", "")
159 .addTask(new ArrayDelegateTask("Disable browser cache only when magnolia.develop=true",
160 new RemoveNodeTask("", "/modules/cache/config/contentCaching/defaultPageCache/browserCachePolicy/policies/never"),
161 new PartialBootstrapTask("", "/mgnl-bootstrap/cache/config.modules.cache.config.contentCaching.defaultPageCache.xml", "/defaultPageCache/browserCachePolicy/policies/disableBrowserCacheInDevelopMode"),
162 new OrderNodeToFirstPositionTask("", "modules/cache/config/contentCaching/defaultPageCache/browserCachePolicy/policies/disableBrowserCacheInDevelopMode")
163 ))
164 );
165 register(DeltaBuilder.update("5.5.5", "")
166 .addTask(new SupportForMultipleCacheImplementationsTask())
167 );
168 register(DeltaBuilder.update("5.6.1", "")
169 .addTask(new BootstrapSingleModuleResource("config.modules.cache.config.contentCaching.defaultPageCache.flushPolicy.policies.lightModule.xml"))
170 .addTask(new NodeExistsDelegateTask("If compression config exists, update JS mime types", "/modules/cache/config/compression/voters/contentType/allowed",
171 new ArrayDelegateTask("Update compression config",
172 new CheckOrCreatePropertyTask("Add gzip support for new JS mime type", "/modules/cache/config/compression/voters/contentType/allowed", "4", "application/javascript"),
173 new HasPropertyDelegateTask("If javascript property is present...",
174 BROWSER_CACHE_POLICIES_CONTENT_TYPE_ALLOWED,
175 "javascript", new ArrayDelegateTask("Rename property and set new value",
176 new RenamePropertyTask("Rename old JS mimetype property in caching policy", RepositoryConstants.CONFIG,
177 BROWSER_CACHE_POLICIES_CONTENT_TYPE_ALLOWED, "javascript", "x-javascript", true),
178 new SetPropertyTask(RepositoryConstants.CONFIG,
179 BROWSER_CACHE_POLICIES_CONTENT_TYPE_ALLOWED, "x-javascript", "application/x-javascript"))
180 ))))
181 .addTask(new NodeExistsDelegateTask("If default page cache config exists, update JS mime types", BROWSER_CACHE_POLICIES_CONTENT_TYPE_ALLOWED,
182 new CheckOrCreatePropertyTask("Add support for new JS mimetype in caching policy",
183 BROWSER_CACHE_POLICIES_CONTENT_TYPE_ALLOWED,
184 "javascript", "application/javascript")))
185 );
186 }
187
188 @Override
189 protected List<Task> getExtraInstallTasks(InstallContext installContext) {
190 final List<Task> tasks = new ArrayList<Task>();
191 tasks.add(placeGzipFilter);
192 tasks.add(placeCacheFilter);
193 tasks.add(addUidlCachePolicy);
194 return tasks;
195 }
196
197 @Override
198 protected List<Task> getStartupTasks(InstallContext installContext) {
199 final List<Task> tasks = new ArrayList<Task>();
200 tasks.addAll(super.getStartupTasks(installContext));
201
202 tasks.add(new RemoveCacheTempFilesTask());
203 return tasks;
204 }
205 }