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.config.mapping;
35
36 import info.magnolia.context.SystemContext;
37 import info.magnolia.jcr.predicate.AbstractPredicate;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.module.googlesitemap.GoogleSiteMapConfiguration;
40 import info.magnolia.module.googlesitemap.SiteMapNodeTypes;
41 import info.magnolia.observation.WorkspaceEventListenerRegistration;
42 import info.magnolia.virtualuri.VirtualUriMapping;
43
44 import java.net.URI;
45 import java.net.URISyntaxException;
46 import java.util.HashMap;
47 import java.util.Iterator;
48 import java.util.Map;
49 import java.util.Optional;
50
51 import javax.inject.Inject;
52 import javax.jcr.Node;
53 import javax.jcr.RepositoryException;
54
55 import org.apache.commons.lang3.StringUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63 public class SiteMapVirtualUriMapping implements VirtualUriMapping {
64
65 public static final String XML_EXTENSION = ".xml";
66
67 private static final Logger log = LoggerFactory.getLogger(SiteMapVirtualUriMapping.class);
68
69 private final SystemContext context;
70
71 private final Map<URI, String> siteMapUrlMappings = new HashMap();
72
73 private String prefix;
74
75 private AbstractPredicate<Node> siteMapNodePredicate = new AbstractPredicate<Node>() {
76 @Override
77 public boolean evaluateTyped(Node node) {
78 try {
79 return NodeUtil.isNodeType(node, SiteMapNodeTypes.SiteMap.NAME);
80 } catch (RepositoryException e) {
81 return false;
82 }
83 }
84 };
85
86 @Inject
87 public SiteMapVirtualUriMapping(SystemContext context) {
88 this.context = context;
89
90 try {
91 WorkspaceEventListenerRegistration.observe(GoogleSiteMapConfiguration.WORKSPACE, "/", events -> reloadSiteMapNames())
92 .withSubNodes(true).register();
93 } catch (RepositoryException e) {
94 log.error("Cannot register workspace listener.", e);
95 }
96 reloadSiteMapNames();
97 }
98
99 private void reloadSiteMapNames() {
100 try {
101 siteMapUrlMappings.clear();
102 Node root = context.getJCRSession(GoogleSiteMapConfiguration.WORKSPACE).getRootNode();
103 final Iterator<Node> it = NodeUtil.collectAllChildren(root, siteMapNodePredicate).iterator();
104 while (it.hasNext()) {
105 Node node = it.next();
106 if (SiteMapNodeTypes.SiteMap.getUrl(node) != null) {
107 URI uri = new URI(SiteMapNodeTypes.SiteMap.getUrl(node));
108 siteMapUrlMappings.put(uri, node.getPath() + XML_EXTENSION);
109 }
110 }
111 } catch (RepositoryException | URISyntaxException e) {
112 log.warn("Failed to collect sitemap names: ", e.getMessage());
113 }
114 }
115
116 @Override
117 public Optional<Result> mapUri(URI uri) {
118 String mapping = siteMapUrlMappings.get(uri);
119 return mapping == null ? Optional.empty() : Optional.of(new Result(prefix + mapping, uri.getPath().length(), this));
120 }
121
122 @Override
123 public boolean isValid() {
124 return StringUtils.isNotEmpty(prefix);
125 }
126
127 public void setPrefix(String prefix) {
128 this.prefix = prefix;
129 }
130 }