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