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