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.googlesitemap.setup.migration;
35
36 import info.magnolia.cms.util.QueryUtil;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.jcr.wrapper.JCRMgnlPropertiesFilteringNodeWrapper;
40 import info.magnolia.jcr.wrapper.JCRPropertiesFilteringNodeWrapper;
41 import info.magnolia.module.InstallContext;
42 import info.magnolia.module.delta.AbstractRepositoryTask;
43 import info.magnolia.module.delta.TaskExecutionException;
44 import info.magnolia.module.googlesitemap.GoogleSiteMapConfiguration;
45 import info.magnolia.repository.RepositoryConstants;
46
47 import java.util.ArrayList;
48 import java.util.Iterator;
49 import java.util.List;
50
51 import javax.jcr.Node;
52 import javax.jcr.NodeIterator;
53 import javax.jcr.Property;
54 import javax.jcr.PropertyIterator;
55 import javax.jcr.RepositoryException;
56 import javax.jcr.Session;
57 import javax.jcr.query.Query;
58
59 import org.apache.commons.lang.StringUtils;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63
64
65
66
67
68
69
70
71
72
73 public class SiteMapDefinitionMigrationTask extends AbstractRepositoryTask {
74
75 private final Logger log = LoggerFactory.getLogger(SiteMapDefinitionMigrationTask.class);
76
77 private final String sourceWorkspace;
78 private final String searchRootPath;
79 private final String templateName = "google-sitemap:pages/siteMapsConfiguration";
80 private final String siteDefinitionTemplateName = "google-sitemap:components/content/siteComponent";
81 private final String virtualUriTemplateName = "google-sitemap:components/content/virtualUriComponent";
82 private Session siteMapSession;
83
84
85 public SiteMapDefinitionMigrationTask(String name, String description, String sourceWorkspace, String searchRootPath) {
86 super(name, description);
87 this.sourceWorkspace = (StringUtils.isNotBlank(sourceWorkspace)) ? sourceWorkspace : RepositoryConstants.WEBSITE;
88 this.searchRootPath = (StringUtils.isNotBlank(searchRootPath)) ? searchRootPath : "/";
89 }
90
91 @Override
92 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
93
94 siteMapSession = installContext.getJCRSession(GoogleSiteMapConfiguration.WORKSPACE);
95 try {
96
97 NodeIterator nodeIterator = getQueryResult();
98
99 while (nodeIterator.hasNext()) {
100 handleSimeMapDefinitionMigration(nodeIterator.nextNode());
101 }
102
103 } catch (RepositoryException re) {
104 installContext.error("Unable to perform Migration task " + getName(), re);
105 throw new TaskExecutionException(re.getMessage());
106 }
107 }
108
109 private void handleSimeMapDefinitionMigration(Node siteMapNodeDefinition) throws RepositoryException {
110
111 Node targetRootSiteMapFolder = getOrCreateRootSiteMapDefinitionNode(siteMapNodeDefinition);
112
113
114 Node targetSiteMapDefinition = migrateSiteMapDefinition(siteMapNodeDefinition, targetRootSiteMapFolder);
115 log.info("New M5 siteMapDefinition created {} based on the previous definition {} ", targetSiteMapDefinition.getPath(), siteMapNodeDefinition.getPath());
116
117
118 siteMapNodeDefinition.remove();
119 }
120
121
122
123
124
125
126
127
128
129 private Node migrateSiteMapDefinition(Node siteMapNodeDefinition, Node targetRootSiteMapFolder) throws RepositoryException {
130
131 Node targetSiteMapDefinition = targetRootSiteMapFolder.addNode(siteMapNodeDefinition.getName(), GoogleSiteMapConfiguration.NODE_TYPE);
132
133 copyOrUpdateProperty(siteMapNodeDefinition, targetSiteMapDefinition);
134
135
136 populateSiteMapDefinition(targetSiteMapDefinition, siteMapNodeDefinition);
137
138 return targetSiteMapDefinition;
139 }
140
141 private void populateSiteMapDefinition(Node targetSiteMapDefinition, Node sourceSiteMapNodeDefinition) throws RepositoryException {
142 List<String> siteMapDefinitionList = new ArrayList<String>();
143 boolean insertVirtualUri = false;
144 Iterable<Node> children = NodeUtil.collectAllChildren(sourceSiteMapNodeDefinition);
145 Iterator<Node> childrenIterator = children.iterator();
146
147 while (childrenIterator.hasNext()) {
148 Node child = childrenIterator.next();
149 if (StringUtils.isNotBlank(NodeTypes.Renderable.getTemplate(child))) {
150 String templateName = NodeTypes.Renderable.getTemplate(child);
151 if (virtualUriTemplateName.equals(templateName)) {
152 insertVirtualUri = true;
153 } else if (siteDefinitionTemplateName.equals(templateName)) {
154 siteMapDefinitionList.addAll(extractSiteMapDefinition(child));
155 }
156 }
157 }
158
159
160 targetSiteMapDefinition.setProperty(GoogleSiteMapConfiguration.INCLUDE_VIRTUAL_URI_MAPPINGS_PROPERTIES, insertVirtualUri);
161
162 if (!siteMapDefinitionList.isEmpty()) {
163 Node sites = targetSiteMapDefinition.addNode("sites", NodeTypes.ContentNode.NAME);
164 int pos = 0;
165 for (String definition : siteMapDefinitionList) {
166 sites.setProperty("" + pos, definition);
167 pos += 1;
168 }
169 }
170 }
171
172 private List<String> extractSiteMapDefinition(Node parent) throws RepositoryException {
173 List<String> siteDefinitions = new ArrayList<String>();
174 if (parent.hasNode(GoogleSiteMapConfiguration.SITE_DIALOG_CONFIGURATION_NAME)) {
175 Node filteredNode = new JCRMgnlPropertiesFilteringNodeWrapper(parent.getNode(GoogleSiteMapConfiguration.SITE_DIALOG_CONFIGURATION_NAME));
176 PropertyIterator iterator = filteredNode.getProperties();
177 while (iterator.hasNext()) {
178 Property property = iterator.nextProperty();
179 siteDefinitions.add(property.getString());
180 }
181 } else {
182 log.info("Node '{}' do not have a 'sites' child node.", parent.getPath());
183 }
184 return siteDefinitions;
185 }
186
187
188
189
190
191 private void copyOrUpdateProperty(Node source, Node target) throws RepositoryException {
192 Node filteredSource = new JCRPropertiesFilteringNodeWrapper(source);
193 PropertyIterator iterator = filteredSource.getProperties();
194 while (iterator.hasNext()) {
195 Property property = iterator.nextProperty();
196 if (target.hasProperty(property.getName())) {
197 target.getProperty(property.getName()).setValue(property.getValue());
198 } else {
199 target.setProperty(property.getName(), property.getValue());
200 }
201 }
202 }
203
204
205
206
207 Node getOrCreateRootSiteMapDefinitionNode(Node siteMapNodeDefinition) throws RepositoryException {
208
209 if (siteMapNodeDefinition.getDepth() <= 1) {
210 return siteMapSession.getRootNode();
211 }
212
213 String targetPath = siteMapNodeDefinition.getParent().getPath();
214 if (siteMapSession.nodeExists(targetPath)) {
215 return siteMapSession.getNode(targetPath);
216 }
217
218 return NodeUtil.createPath(siteMapSession.getRootNode(), targetPath, NodeTypes.Folder.NAME, false);
219 }
220
221
222
223
224 private NodeIterator getQueryResult() throws RepositoryException {
225 NodeIterator nodeIterator = null;
226 String query = "SELECT * FROM [nt:base] AS t WHERE (ISSAMENODE(t, '" + searchRootPath + "') OR ISDESCENDANTNODE(t, '" + searchRootPath + "')) " +
227 "AND t.[mgnl:template] is not null AND contains(t.[" + NodeTypes.Renderable.TEMPLATE + "],'" + templateName + "')";
228 nodeIterator = QueryUtil.search(sourceWorkspace, query, Query.JCR_SQL2);
229 log.info("{} google site map definitions will be handled", nodeIterator.getSize());
230 return nodeIterator;
231 }
232 }