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.templatingkit.redirection.validator;
35
36 import info.magnolia.context.MgnlContext;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.jcr.util.PropertyUtil;
40 import info.magnolia.repository.RepositoryConstants;
41 import info.magnolia.ui.vaadin.integration.jcr.JcrItemAdapter;
42
43 import javax.jcr.Node;
44 import javax.jcr.RepositoryException;
45 import javax.jcr.Session;
46
47 import org.apache.commons.lang3.StringUtils;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import com.vaadin.data.Item;
52 import com.vaadin.data.validator.AbstractValidator;
53
54
55
56
57
58
59
60
61
62 public class RedirectTargetValidator extends AbstractValidator<String> {
63
64 private final static Logger log = LoggerFactory.getLogger(RedirectTargetValidator.class);
65
66 private static final String indirectRedirectPathLeadingTo404 = "indirectRedirectPathLeadingTo404";
67 private static final String circularRedirection = "circularRedirection";
68 private static final String redirectTo404 = "redirectTo404";
69
70 private final Item item;
71 private final RedirectTargetValidatorDefinition definition;
72 private String errorMessageType = circularRedirection;
73
74 public RedirectTargetValidator(Item item, RedirectTargetValidatorDefinition definition) {
75 super(null);
76 this.item = item;
77 this.definition = definition;
78 }
79
80 @Override
81 public Class<String> getType() {
82 return String.class;
83 }
84
85 @Override
86 public String getErrorMessage() {
87 if (circularRedirection.equals(errorMessageType)) {
88 return definition.getErrorMessage();
89 } else {
90 return definition.getErrorMessageFor404();
91 }
92 }
93
94 @Override
95 protected boolean isValidValue(String targetPagePath) {
96 if (StringUtils.isEmpty(targetPagePath)) {
97 return true;
98 }
99
100 try {
101 errorMessageType = circularRedirection;
102 final Session session = MgnlContext.getJCRSession(RepositoryConstants.WEBSITE);
103 final Node currentPage = (Node) ((JcrItemAdapter) item).getJcrItem();
104 final String currentPageLocation = currentPage.getPath();
105
106
107 if (targetPagePath.equals(currentPageLocation)) {
108 return false;
109 }
110
111
112
113 final String indirectRedirectionPath = findCascadedRedirectionTarget(targetPagePath, session, currentPageLocation);
114 if (indirectRedirectPathLeadingTo404.equals(indirectRedirectionPath)) {
115 errorMessageType = redirectTo404;
116 return false;
117 } else if (circularRedirection.equals(indirectRedirectionPath)) {
118 return false;
119 } else if (indirectRedirectionPath == null) {
120 return true;
121 }
122 } catch (RepositoryException e) {
123 log.error("Failed to fetch jcr data.", e);
124 }
125
126
127 return false;
128 }
129
130
131
132
133
134
135
136
137
138 private String findCascadedRedirectionTarget(String redirectPath, Session session, String currentNodePath) throws RepositoryException {
139 final Node redirectionTargetNode = session.getNode(redirectPath);
140
141
142 if (isRedirectPage(redirectionTargetNode)) {
143 final String nextRedirectionPath = PropertyUtil.getString(redirectionTargetNode, "path");
144
145
146 if (StringUtils.isEmpty(nextRedirectionPath)) {
147 final Iterable<Node> children = NodeUtil.getNodes(redirectionTargetNode, NodeTypes.Page.NAME);
148
149 if (children != null && children.iterator().hasNext()) {
150 final Node firstChild = children.iterator().next();
151
152
153 if (!isRedirectPage(firstChild)) {
154 return null;
155 } else {
156 return findCascadedRedirectionTarget(firstChild.getPath(), session, currentNodePath);
157 }
158
159 } else {
160 return indirectRedirectPathLeadingTo404;
161 }
162 } else {
163 if (currentNodePath.equals(nextRedirectionPath)) {
164 return circularRedirection;
165 } else {
166 return findCascadedRedirectionTarget(nextRedirectionPath, session, currentNodePath);
167 }
168 }
169 }
170 return null;
171 }
172
173 private boolean isRedirectPage(Node pageNode) throws RepositoryException {
174 final String templateId = PropertyUtil.getString(pageNode, NodeTypes.Renderable.TEMPLATE);
175 return StringUtils.equals(definition.getTemplateId(), templateId);
176 }
177
178 }