View Javadoc
1   /**
2    * This file Copyright (c) 2012-2016 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.admincentral.setup;
35  
36  import static info.magnolia.nodebuilder.Ops.*;
37  
38  import info.magnolia.cms.core.ItemType;
39  import info.magnolia.jcr.util.NodeTypeTemplateUtil;
40  import info.magnolia.jcr.util.NodeTypes;
41  import info.magnolia.module.DefaultModuleVersionHandler;
42  import info.magnolia.module.InstallContext;
43  import info.magnolia.module.delta.AbstractTask;
44  import info.magnolia.module.delta.ArrayDelegateTask;
45  import info.magnolia.module.delta.BootstrapSingleModuleResource;
46  import info.magnolia.module.delta.BootstrapSingleResource;
47  import info.magnolia.module.delta.ChangeAllPropertiesWithCertainValueTask;
48  import info.magnolia.module.delta.CheckAndModifyPropertyValueTask;
49  import info.magnolia.module.delta.CheckOrCreatePropertyTask;
50  import info.magnolia.module.delta.ConditionalDelegateTask;
51  import info.magnolia.module.delta.CreateNodePathTask;
52  import info.magnolia.module.delta.CreateNodeTask;
53  import info.magnolia.module.delta.DeltaBuilder;
54  import info.magnolia.module.delta.IsModuleInstalledOrRegistered;
55  import info.magnolia.module.delta.MoveNodeTask;
56  import info.magnolia.module.delta.NewPropertyTask;
57  import info.magnolia.module.delta.NodeExistsDelegateTask;
58  import info.magnolia.module.delta.OrderNodeAfterTask;
59  import info.magnolia.module.delta.OrderNodeBeforeTask;
60  import info.magnolia.module.delta.OrderNodeToFirstPositionTask;
61  import info.magnolia.module.delta.PartialBootstrapTask;
62  import info.magnolia.module.delta.PropertyExistsDelegateTask;
63  import info.magnolia.module.delta.PropertyValueDelegateTask;
64  import info.magnolia.module.delta.RemoveNodeTask;
65  import info.magnolia.module.delta.RemovePropertyTask;
66  import info.magnolia.module.delta.RenameNodesTask;
67  import info.magnolia.module.delta.SetPropertyTask;
68  import info.magnolia.module.delta.Task;
69  import info.magnolia.module.delta.TaskExecutionException;
70  import info.magnolia.nodebuilder.task.ErrorHandling;
71  import info.magnolia.nodebuilder.task.NodeBuilderTask;
72  import info.magnolia.repository.RepositoryConstants;
73  import info.magnolia.setup.for5_0.AbstractNodeTypeRegistrationTask;
74  import info.magnolia.ui.admincentral.dialog.action.CancelDialogActionDefinition;
75  import info.magnolia.ui.admincentral.dialog.action.SaveConfigDialogActionDefinition;
76  import info.magnolia.ui.admincentral.dialog.action.SaveDialogActionDefinition;
77  import info.magnolia.ui.admincentral.dialog.action.SaveImportDialogActionDefinition;
78  import info.magnolia.ui.admincentral.setup.for5_3.WidgetsetRelocationCondition;
79  import info.magnolia.ui.admincentral.setup.for5_5.RemoveAdmininterfaceLegacyTask;
80  import info.magnolia.ui.api.app.registry.ConfiguredAppDescriptor;
81  import info.magnolia.ui.framework.AdmincentralNodeTypes;
82  import info.magnolia.ui.framework.favorite.FavoriteStore;
83  import info.magnolia.ui.framework.setup.AddIsPublishedRuleToAllDeactivateActionsTask;
84  
85  import java.util.ArrayList;
86  import java.util.Arrays;
87  import java.util.HashMap;
88  import java.util.List;
89  import java.util.Map;
90  
91  import javax.jcr.RepositoryException;
92  import javax.jcr.nodetype.NodeTypeDefinition;
93  import javax.jcr.nodetype.NodeTypeManager;
94  
95  import org.apache.jackrabbit.JcrConstants;
96  
97  /**
98   * VersionHandler for the Admincentral module.
99   */
100 public class AdmincentralModuleVersionHandler extends DefaultModuleVersionHandler {
101 
102     protected static final String UI_ACTIONS_IMPORT = "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/import";
103     protected static final String UI_IMPORT_FIELD = "/modules/ui-admincentral/dialogs/import/form/tabs/import/fields/name";
104     protected static final String UI_ADMINCENTRAL_DIALOGS = "/modules/ui-admincentral/dialogs";
105 
106     private final Task excludeProfilesAndMessagesWorkspacesFromFlushCachePolicy = new ExcludeWorkspacesFromFlushCachePolicy("profiles", "messages");
107 
108     /**
109      * Check if the activation module is install and correctly configured.
110      */
111     private class RunConfigureActivationDelegateTask extends ConditionalDelegateTask {
112 
113         public RunConfigureActivationDelegateTask(String taskName, String taskDescription, Task ifTrue) {
114             super(taskName, taskDescription, ifTrue);
115         }
116 
117         @Override
118         public boolean condition(InstallContext ctx) {
119             try {
120                 return ctx.isModuleRegistered("activation") && ctx.getConfigJCRSession().nodeExists("/modules/activation")
121                         && (!ctx.getConfigJCRSession().nodeExists("/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/activation")
122                         || !ctx.getConfigJCRSession().nodeExists("/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/activationMonitor"));
123             } catch (RepositoryException e) {
124                 return false;
125             }
126         }
127     }
128 
129     private ArrayDelegateTask createActivationConfig = new ArrayDelegateTask("",
130             new NodeExistsDelegateTask("Create node", "Create path.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps", null,
131                     new CreateNodePathTask("Create node", "Create path.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps", ItemType.CONTENTNODE)),
132             new NodeExistsDelegateTask("Create node", "Create entry in tools group of appLauncher for Activation tools.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/activation", null,
133                     new CreateNodeTask("Create node", "Create entry in tools group of appLauncher for Activation tools.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps", "activation", NodeTypes.ContentNode.NAME)),
134             new NodeExistsDelegateTask("Create node", "Create entry in tools group of appLauncher for Activation monitor.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/activationMonitor", null,
135                     new CreateNodeTask("Create node", "Create entry in appLauncher for Activation monitor.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps", "activationMonitor", NodeTypes.ContentNode.NAME)));
136 
137     private final Task addDownloadAsYamlActionTask = new AbstractTask("Download as Yaml action", "Add download as Yaml action to configuration app.") {
138 
139         private final String appBootstrapFilePath = "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml";
140         private final String commandsBootstrapFilePath = "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.commands.xml";
141         private final String actionBarFolderActionGroupsPath = "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar/sections/folders/groups";
142 
143         private ArrayDelegateTask delegate = new ArrayDelegateTask(getName(),
144                 new PartialBootstrapTask("", "Register command", commandsBootstrapFilePath, "/commands/default/exportYaml"),
145                 new NodeExistsDelegateTask("", actionBarFolderActionGroupsPath,
146                         new ArrayDelegateTask("",
147                                 new CreateNodePathTask("", String.format("%s/%s", actionBarFolderActionGroupsPath, "downloadActions/items"), NodeTypes.ContentNode.NAME),
148                                 new PartialBootstrapTask("", "Register in action bar", appBootstrapFilePath, "/configuration/subApps/browser/actionbar/sections/folders/groups/downloadActions/items/downloadYaml"),
149                                 new NodeExistsDelegateTask("", String.format("%s/%s", actionBarFolderActionGroupsPath, "importExportActions"),
150                                         new OrderNodeBeforeTask(String.format("%s/%s", actionBarFolderActionGroupsPath, "downloadActions"), "importExportActions")),
151                                 new PartialBootstrapTask("", "Add to app actions", appBootstrapFilePath, "/configuration/subApps/browser/actions/downloadYaml"))));
152 
153         @Override
154         public void execute(InstallContext installContext) throws TaskExecutionException {
155             delegate.execute(installContext);
156         }
157     };
158 
159     public AdmincentralModuleVersionHandler() {
160 
161         register(DeltaBuilder.update("5.0", "")
162                 .addTask(new ConvertListAclToAppPermissionsTask("Convert permissions for 'ui-admincentral' apps", "Convert ACL permissions to old menus to new admincentral apps permission", this.getAclsToAppsPermissionsMap(), true)));
163 
164         register(DeltaBuilder.update("5.0.1", "")
165                 .addTask(new NodeExistsDelegateTask("Remove dialog links Node", "Remove dialog definition in ui-admincentral/dialogs/links", RepositoryConstants.CONFIG, "/modules/ui-admincentral/dialogs/link",
166                         new RemoveNodeTask("Remove dialog links Node", "Remove dialog definition in ui-admincentral/dialogs/links", RepositoryConstants.CONFIG, "/modules/ui-admincentral/dialogs/link")))
167 
168                 .addTask(new PartialBootstrapTask("Add editProperty dialog", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.dialogs.xml", "/dialogs/editProperty"))
169                 .addTask(new PartialBootstrapTask("Add editProperty action to Configuration app", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/editProperty"))
170 
171                 .addTask(new PartialBootstrapTask("Add renameItem dialog", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.dialogs.xml", "/dialogs/renameItem"))
172                 .addTask(new PartialBootstrapTask("Add rename action to Configuration app", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/rename"))
173 
174                 // Update actionbars
175                 .addTask(new NodeExistsDelegateTask("Remove duplicateActions section from Configuration app.", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar/sections/folders/groups/duplicateActions",
176                         new RemoveNodeTask("Remove duplicateActions section from Configuration app", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar/sections/folders/groups/duplicateActions")))
177                 .addTask(new PartialBootstrapTask("Add editActions section to Configuration app", "Adds editProperty, rename, and duplicate actions.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actionbar/sections/folders/groups/editActions"))
178                 .addTask(new OrderNodeAfterTask("Move editActions section after addingActions", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar/sections/folders/groups/editActions", "addingActions"))
179 
180                 // JCR App should extend Configuration App.
181                 .addTask(new NodeExistsDelegateTask("Remove websiteJcrBrowser App subApps.", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/websiteJcrBrowser/subApps",
182                         new RemoveNodeTask("Remove websiteJcrBrowser App subApps.", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/websiteJcrBrowser/subApps")))
183                 .addTask(new PartialBootstrapTask("Add updated websiteJcrBrowser App subApps.", "It now extends Configuration app.", "/mgnl-bootstrap-prior-5_3/config.modules.ui-admincentral.apps.websiteJcrBrowser.xml", "/websiteJcrBrowser/subApps"))
184 
185         );
186 
187         register(DeltaBuilder.update("5.0.2", "")
188                 // new action for confirmation
189                 .addTask(new PartialBootstrapTask("Add new confirmation action definition", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/confirmDeletion"))
190 
191                 .addTask(new NodeExistsDelegateTask("Remove action availability from delete action", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete/availability",
192                         new RemoveNodeTask("", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete/availability")))
193                 .addTask(new PropertyExistsDelegateTask("Remove label for delete action", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete", "label",
194                         new RemovePropertyTask("Remove label for delete action", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete", "label")))
195                 .addTask(new PropertyExistsDelegateTask("Remove icon for delete action", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete", "icon",
196                         new RemovePropertyTask("Remove icon for delete action", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete", "icon")))
197 
198                 // update actionbar for confirmation
199                 .addTask(new NodeExistsDelegateTask("Update actionbar configuration", "Rename action mapping to new confirmation action", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar",
200                         new RenameNodesTask("Rename action bar items", "Rename delete to confirmDeletion", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar", "delete", "confirmDeletion", NodeTypes.ContentNode.NAME))));
201 
202         register(DeltaBuilder.update("5.1", "")
203                 .addTask(new PartialBootstrapTask("Bootstrap new actionbar section in Configuration app", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actionbar/sections/multiple"))
204                 .addTask(new PartialBootstrapTask("JCR browser app node types", "Bootstraps the new node types configuration for the JCR browser app", "/mgnl-bootstrap-prior-5_3/config.modules.ui-admincentral.apps.websiteJcrBrowser.xml", "/websiteJcrBrowser/subApps/browser/workbench/nodeTypes"))
205                 .addTask(new NewPropertyTask("Set multiple=true in confirmDeletion action's availability.", "Sets multiple=true in confirmDeletion action's availability., i.e. the Delete action now supports multiple items.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/confirmDeletion/availability", "multiple", true))
206                 .addTask(new NewPropertyTask("Set main node type in configuration app as strict", "Sets main node type as strict, i.e. its substypes won't be included in list and search views.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/workbench/nodeTypes/mainNodeType", "strict", true))
207                 .addTask(new NewPropertyTask("Set folder node type in configuration app as strict", "Sets folder node type as strict, i.e. its substypes won't be included in list and search views.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/workbench/nodeTypes/folderNodeType", "strict", true))
208                 .addTask(new NodeExistsDelegateTask("Conditional move of configuration of the appLauncherLayout from the ui-framework to the ui-admincentral", "Moves the the conf. of the appLauncherLayout from the ui-framework to the ui-admincentral (if the node exists)", RepositoryConstants.CONFIG, "/modules/ui-framework/config/appLauncherLayout", new MoveNodeTask("Move configuration of the appLauncherLayout from the ui-framework to the ui-admincentral", "Moves the the conf. of the appLauncherLayout from the ui-framework to the ui-admincentral", RepositoryConstants.CONFIG, "/modules/ui-framework/config/appLauncherLayout", "/modules/ui-admincentral/config/appLauncherLayout", false)))
209                 .addTask(new NodeExistsDelegateTask("Conditional removal of the node /modules/ui-framework/config", "Removes the node /modules/ui-framework/config if it exists (it should empty)", RepositoryConstants.CONFIG, "/modules/ui-framework/config", new RemoveNodeTask("Removing the empty node /modules/ui-framework/config", "Removes the empty node /modules/ui-framework/config", RepositoryConstants.CONFIG, "/modules/ui-framework/config")))
210                 .addTask(new RemoveHardcodedI18nPropertiesFromAdmincentralTask())
211 
212                 // update vaadin servlet params (we inject a custom UIProvider instead)
213                 .addTask(new PropertyExistsDelegateTask("Check widgetset servlet param", "Checks if widgetset is configured as servlet parameter", RepositoryConstants.CONFIG, "/server/filters/servlets/AdminCentral/parameters", "widgetset",
214                         new RemovePropertyTask("Remove widgetset servlet param", "Removes the widgetset property from AdminCentral servlet parameters", RepositoryConstants.CONFIG, "/server/filters/servlets/AdminCentral/parameters", "widgetset")))
215 
216                 .addTask(new PartialBootstrapTask("Bootstrap move action in Configuration app", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/move"))
217                 .addTask(new PartialBootstrapTask("Bootstrap move action to Configuration app actionbar", "Adds action move to folder/editActions actionbar.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actionbar/sections/folders/groups/editActions/items/move")));
218 
219         register(DeltaBuilder.update("5.1.1", "")
220 
221                 // update favorite node type
222                 .addTask(new AbstractNodeTypeRegistrationTask("Update favorite node type", "This task ensures the mgnl:favorite node type is updated with its appropriate mixin supertypes.", FavoriteStore.WORKSPACE_NAME) {
223 
224                     @Override
225                     public List<String> getNodeTypesToUnregister(NodeTypeManager nodeTypeManager) {
226                         return null;
227                     }
228 
229                     @Override
230                     public List<NodeTypeDefinition> getNodeTypesToRegister(NodeTypeManager nodeTypeManager) throws RepositoryException {
231                         List<NodeTypeDefinition> types = new ArrayList<>();
232 
233                         types.add(NodeTypeTemplateUtil.createSimpleNodeType(nodeTypeManager,
234                                         AdmincentralNodeTypes.Favorite.NAME,
235                                         Arrays.asList(
236                                                 JcrConstants.NT_BASE,
237                                                 NodeTypes.Created.NAME,
238                                                 NodeTypes.LastModified.NAME))
239                         );
240 
241                         return types;
242                     }
243                 }));
244 
245         register(DeltaBuilder.update("5.1.2", "")
246                 .addTask(new PartialBootstrapTask("Configuration app", "Change availability of add folder action", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/addFolder/availability/nodeTypes"))
247                 .addTask(new RemovePropertyTask("Remove hardcoded icon", "Remove hardcoded icon of Configuration app", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration", "icon"))
248                 .addTask(new RemovePropertyTask("Remove hardcoded icon", "Remove hardcoded icon of JCR app", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/websiteJcrBrowser", "icon")));
249 
250         register(DeltaBuilder.update("5.2", "")
251                 .addTask(new BootstrapSingleModuleResource("Bootstrap virtualURIMapping", "Bootstrap virtual URI mappings which have moved from adminInterface module.", "config.modules.ui-admincentral.virtualURIMapping.xml")));
252 
253         register(DeltaBuilder.update("5.2.1", "")
254                 .addTask(new IsModuleInstalledOrRegistered("Create node", "Create entry in tools group of appLauncher for Activation tools.", "activation",
255                         createActivationConfig))
256                 .addTask(new NodeExistsDelegateTask("Reorder JCR in TOOLS group", "This reorders the JCR app before Activation in the Tools group of the applauncher.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/activation",
257                         new OrderNodeBeforeTask("", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/websiteJcrBrowser", "activation"))));
258 
259         register(DeltaBuilder.update("5.2.2", "")
260                 .addTask(new RunConfigureActivationDelegateTask("Correct miss configuration of the activation module", "", createActivationConfig))
261                 .addTask(new PropertyExistsDelegateTask("Remove obsolete property if exists", "", RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/stkSiteApp", "icon",
262                         new RemovePropertyTask("Remove obsolete property", "Remove obsolete '/modules/ui-admincentral/apps/stkSiteApp/icon'",
263                                 RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/stkSiteApp", "icon")))
264                 .addTask(new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/commands/default/delete/deactivate", "enabled", "true"))
265                 .addTask(new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/templates/deleted", "i18nBasename", "info.magnolia.module.admininterface.messages"))
266                 .addTask(new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration", "class", ConfiguredAppDescriptor.class.getName()))
267                 .addTask(new RemoveNodeTask("Delete ICEPush MIME mapping", "ICEPush is no longer used an thus its MIME-mapping should be removed", RepositoryConstants.CONFIG, "/server/MIMEMapping/icepush"))
268                 .addTask(new NodeExistsDelegateTask("Reconfigure activate action of configuration app", "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/activate",
269                         new PartialBootstrapTask("Reconfigure activate action of configuration app", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/activate/params"))));
270 
271         register(DeltaBuilder.update("5.2.4", "")
272                 .addTask(new ArrayDelegateTask("Update user menu", "This task updates the user menu with icons and a new action to edit user profile.",
273                         new NodeExistsDelegateTask("Logout icon", "This task adds an icon to logout user menu entry.", RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/userMenu/actions/logout",
274                                 new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/config/userMenu/actions/logout", "icon", "icon-redo")),
275                         new PartialBootstrapTask("Edit user profile dialog", "This task adds dialog to edit user profile.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.dialogs.xml", "/dialogs/editUserProfile"),
276                         new PartialBootstrapTask("Edit user profile action", "This taks adds the edit user profile action to user menu.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.config.userMenu.xml", "/userMenu/actions/editUserProfile"),
277                         new OrderNodeToFirstPositionTask("Order edit user profile action to first position in user menu", "modules/ui-admincentral/config/userMenu/actions/editUserProfile")))
278                 .addTask(new CheckAndModifyPropertyValueTask("/modules/ui-admincentral/apps/configuration/", "class", "info.magnolia.ui.api.app.registry.ConfiguredAppDescriptor", "info.magnolia.ui.contentapp.ContentAppDescriptor")));
279 
280         register(DeltaBuilder.update("5.2.5", "")
281                 .addTask(new IsModuleInstalledOrRegistered("Configure recursive activation and deletion as asynchronous", "scheduler", new ArrayDelegateTask("",
282                         new NodeExistsDelegateTask("Configure recursive activation as asynchronous", "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/activateRecursive",
283                                 new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/activateRecursive", "asynchronous", "true")),
284                         new NodeExistsDelegateTask("Configure deletion as asynchronous", "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete",
285                                 new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete", "asynchronous", "true")),
286                         new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.messageViews.xml", "/messageViews/longRunning")
287                 ))));
288 
289         register(DeltaBuilder.update("5.2.7", "")
290                 .addTask(new NodeExistsDelegateTask("Allow import action at root level in configuration and STK apps", UI_ACTIONS_IMPORT,
291                         new NodeBuilderTask("Allow import action at root level in configuration and STK apps", "", ErrorHandling.logging, RepositoryConstants.CONFIG, UI_ACTIONS_IMPORT,
292                                 addNode("availability", NodeTypes.ContentNode.NAME).then(
293                                         addProperty("root", true))))));
294 
295         register(DeltaBuilder.update("5.3", "")
296                 .addTask(new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/workbench", "dropConstraintClass", "info.magnolia.ui.workbench.tree.drop.NodesAndPropsDropConstraint"))
297                 .addTask(new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/move/availability", "properties", "true"))
298                 .addCondition(new WidgetsetRelocationCondition()));
299 
300         register(DeltaBuilder.update("5.3.2", "")
301                 .addTask(new NodeExistsDelegateTask("Create a new property required in '/modules/ui-admincentral/dialogs/import/form/tabs/import/fields/name' with true value", UI_IMPORT_FIELD,
302                         new CheckOrCreatePropertyTask("Create a new property required in '/modules/ui-admincentral/dialogs/import/form/tabs/import/fields/name' with true value", UI_IMPORT_FIELD, "required", "true"))));
303         register(DeltaBuilder.update("5.3.4", "")
304                 .addTask(new PartialBootstrapTask("Add restorePreviousVersion command", "Adds restorePreviousVersion command.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.commands.xml", "/commands/default/restorePreviousVersion")));
305         register(DeltaBuilder.update("5.3.6", "")
306                 .addTask(new AddIsPublishedRuleToAllDeactivateActionsTask("","/modules/ui-admincentral/apps/"))
307         );
308         register(DeltaBuilder.update("5.3.9", "")
309                 .addTask(new PartialBootstrapTask("Add ConfigProtectedNodeRule rule to deactivation action.", "Add ConfigProtectedNodeRule rule to deactivation action.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/deactivate/availability/rules/ConfigProtectedNodeRule"))
310         );
311         register(DeltaBuilder.update("5.4", "")
312                 .addTask(new BootstrapSingleResource("Bootstrap Pulse Presenters", "Bootstrap the new configuration for tasks and messages in Pulse.", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.config.pulse.xml"))
313                 .addTask(excludeProfilesAndMessagesWorkspacesFromFlushCachePolicy)
314                 .addTask(new CheckAndModifyPropertyValueTask("Fix default login form", "Fixes the location of the default login form.", RepositoryConstants.CONFIG, "/server/filters/securityCallback/clientCallbacks/form", "loginForm", "/mgnl-resources/defaultLoginForm/login.html", "/defaultMagnoliaLoginForm/login.html"))
315                 .addTask(new CheckAndModifyPropertyValueTask("Fix default login form", "Fixes the permissions to enable access to the default login form.", RepositoryConstants.CONFIG, "/server/filters/uriSecurity/bypasses/login", "pattern", "/.resources/defaultLoginForm", "/.resources/defaultMagnoliaLoginForm"))
316         );
317         register(DeltaBuilder.update("5.4.1", "")
318                 .addTask(addDownloadAsYamlActionTask)
319                 .addTask(new NodeExistsDelegateTask("", "/modules/ui-admincentral/messageViews/longRunning",
320                         new PartialBootstrapTask("Add exception field to longRunning messageView", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.messageViews.xml", "/messageViews/longRunning/form/tabs/message/fields/exception"))));
321         register(DeltaBuilder.update("5.4.4", "")
322                 .addTask(new RemoveNodeTask("Remove Website Jcr Browser app from App Launcher", "/modules/ui-admincentral/config/appLauncherLayout/groups/tools/apps/websiteJcrBrowser")));
323 
324         register(DeltaBuilder.update("5.4.7", "")
325                 .addTask(new ArrayDelegateTask("Improve user profile dialog",
326                         new BootstrapSingleResource("", "", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.fieldTypes.xml"),
327                         new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.dialogs.xml", "dialogs/editUserProfile/form/tabs/preferences"),
328                         new PropertyValueDelegateTask("", "/modules/ui-admincentral/dialogs/editUserProfile/form/tabs/preferences/fields/language", "class", "info.magnolia.security.app.dialog.field.SystemLanguagesFieldDefinition", true,
329                                 new RemoveNodeTask("", "/modules/ui-admincentral/dialogs/editUserProfile/form/tabs/user/fields/language"),
330                                 new MoveNodeTask("", "/modules/ui-admincentral/dialogs/editUserProfile/form/tabs/user/fields/language", "/modules/ui-admincentral/dialogs/editUserProfile/form/tabs/preferences/fields/language", true)
331                         )
332                 ))
333         );
334 
335         register(DeltaBuilder.update("5.5", "")
336                 .addTask(new ArrayDelegateTask("Bulk actions", "Add configuration for bulk actions to footer.",
337                         new PartialBootstrapTask("", "Register task action", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.config.pulse.xml", "/pulse/presenters/tasks/bulkActions"),
338                         new PartialBootstrapTask("", "Register message action", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.config.pulse.xml", "/pulse/presenters/messages/bulkActions")))
339                 .addTask(new ArrayDelegateTask("Add copy and paste functionality into configuration browser.", "Add ability to copy and paste the items in configuration browser.",
340                     new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/copy"),
341                     new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actions/paste"),
342                     new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actionbar/sections/folders/groups/editActions/items/copy"),
343                     new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.apps.configuration.xml", "/configuration/subApps/browser/actionbar/sections/folders/groups/editActions/items/paste"),
344                     new OrderNodeAfterTask("", "/modules/ui-admincentral/apps/configuration/subApps/browser/actionbar/sections/folders/groups/editActions/items/paste", "copy")))
345                 .addTask(new ArrayDelegateTask("Reconfigure class properties of dialog actions to not use deprecated classes.",
346                         new ChangeAllPropertiesWithCertainValueTask(RepositoryConstants.CONFIG, UI_ADMINCENTRAL_DIALOGS, SaveImportDialogActionDefinition.class.getName(), info.magnolia.ui.dialog.action.SaveImportDialogActionDefinition.class.getName()),
347                         new ChangeAllPropertiesWithCertainValueTask(RepositoryConstants.CONFIG, UI_ADMINCENTRAL_DIALOGS, CancelDialogActionDefinition.class.getName(), info.magnolia.ui.dialog.action.CancelDialogActionDefinition.class.getName()),
348                         new ChangeAllPropertiesWithCertainValueTask(RepositoryConstants.CONFIG, UI_ADMINCENTRAL_DIALOGS, SaveConfigDialogActionDefinition.class.getName(), info.magnolia.ui.dialog.action.SaveConfigDialogActionDefinition.class.getName()),
349                         new ChangeAllPropertiesWithCertainValueTask(RepositoryConstants.CONFIG, UI_ADMINCENTRAL_DIALOGS, SaveDialogActionDefinition.class.getName(), info.magnolia.ui.dialog.action.SaveDialogActionDefinition.class.getName()))
350                 )
351 
352                 .addTask(new RemoveAdmininterfaceLegacyTask())
353                 .addTask(new PropertyExistsDelegateTask("Remove admininterface-legacy unused i18n property", "/modules/ui-admincentral/templates/deleted", "i18nBasename",
354                         new RemovePropertyTask("", "/modules/ui-admincentral/templates/deleted", "i18nBasename")))
355                 .addTask(new NodeExistsDelegateTask("", "/modules/ui-admincentral/apps/websiteJcrBrowser", new RemoveNodeTask("", "/modules/ui-admincentral/apps/websiteJcrBrowser")))
356         );
357     }
358 
359     @Override
360     protected List<Task> getExtraInstallTasks(InstallContext installContext) {
361         List<Task> list = new ArrayList<>();
362 
363         list.add(new IsModuleInstalledOrRegistered(
364                 "Replace login security pattern",
365                 "Replaces old login security pattern '/.resources/loginForm' (if present) with the new one '/.resources/defaultMagnoliaLoginForm'.",
366                 "adminInterface",
367                 new CheckAndModifyPropertyValueTask(
368                         "",
369                         "",
370                         RepositoryConstants.CONFIG,
371                         "/server/filters/uriSecurity/bypasses/login",
372                         "pattern",
373                         "/.resources/loginForm",
374                         "/.resources/defaultMagnoliaLoginForm")));
375         list.add(new NodeExistsDelegateTask("Remove PageEditorServlet from configuration", "Remove 4.5.x PageEditorServlet from the servlet registration. ", RepositoryConstants.CONFIG, "/server/filters/servlets/PageEditorServlet",
376                 new RemoveNodeTask("Remove PageEditorServlet from configuration", "Remove 4.5.x PageEditorServlet from the servlet registration. ", RepositoryConstants.CONFIG, "/server/filters/servlets/PageEditorServlet")));
377         list.add(new IsModuleInstalledOrRegistered("Configure recursive activation and deletion as asynchronous", "scheduler", new ArrayDelegateTask("",
378                 new NodeExistsDelegateTask("Configure recursive activation as asynchronous", "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/activateRecursive",
379                         new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/activateRecursive", "asynchronous", "true")),
380                 new NodeExistsDelegateTask("Configure deletion as asynchronous", "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete",
381                         new SetPropertyTask(RepositoryConstants.CONFIG, "/modules/ui-admincentral/apps/configuration/subApps/browser/actions/delete", "asynchronous", "true")),
382                 new PartialBootstrapTask("", "/mgnl-bootstrap/ui-admincentral/config.modules.ui-admincentral.messageViews.xml", "/messageViews/longRunning"))));
383 
384         list.add(excludeProfilesAndMessagesWorkspacesFromFlushCachePolicy);
385         return list;
386     }
387 
388     private Map<String, String[]> getAclsToAppsPermissionsMap() {
389         Map<String, String[]> permissionsMap = new HashMap<>();
390 
391         // DEV and TOOLS menu
392         permissionsMap.put("/modules/adminInterface/config/menu/tools", new String[] { // old 'Tools' menu is in 5 is split into two
393                 "/modules/ui-admincentral/config/appLauncherLayout/groups/tools", "/modules/ui-admincentral/config/appLauncherLayout/groups/dev"
394         });
395 
396         permissionsMap.put("/modules/adminInterface/config/menu/tools/websiteJCR", new String[]{"/modules/ui-admincentral/apps/websiteJcrBrowser"});
397         permissionsMap.put("/.magnolia/trees/config", new String[]{"/modules/ui-admincentral/apps/configuration"});
398 
399         // DATA menu
400         permissionsMap.put("/modules/adminInterface/config/menu/templating-kit/data", new String[] { "/modules/ui-admincentral/config/appLauncherLayout/groups/data" });
401 
402         return permissionsMap;
403     }
404 
405 }