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