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.ui.editor.validator;
35
36
37 import info.magnolia.i18nsystem.SimpleTranslator;
38 import info.magnolia.jcr.util.NodeNameHelper;
39 import info.magnolia.objectfactory.Components;
40 import info.magnolia.ui.datasource.jcr.JcrDatasource;
41 import info.magnolia.ui.field.AbstractFieldValidatorFactory;
42
43 import java.util.Optional;
44
45 import javax.inject.Inject;
46 import javax.jcr.Item;
47 import javax.jcr.Node;
48 import javax.jcr.RepositoryException;
49
50 import org.apache.commons.lang3.StringUtils;
51
52 import com.machinezoo.noexception.Exceptions;
53 import com.vaadin.data.ValidationResult;
54 import com.vaadin.data.Validator;
55 import com.vaadin.data.ValueContext;
56 import com.vaadin.data.validator.RegexpValidator;
57
58
59
60
61 public class NodeNameFieldValidatorFactory extends AbstractFieldValidatorFactory<NodeNameValidatorDefinition, String> {
62
63 private final info.magnolia.ui.ValueContext<Item> valueContext;
64 private final SimpleTranslator simpleTranslator;
65 private final NodeNameHelper nodeNameHelper;
66 private final JcrDatasource jcrDatasource;
67
68 @Inject
69 NodeNameFieldValidatorFactory(NodeNameValidatorDefinition definition, info.magnolia.ui.ValueContext<Item> valueContext, SimpleTranslator simpleTranslator, NodeNameHelper nodeNameHelper, JcrDatasource jcrDatasource) {
70 super(definition);
71 this.valueContext = valueContext;
72 this.simpleTranslator = simpleTranslator;
73 this.nodeNameHelper = nodeNameHelper;
74 this.jcrDatasource = jcrDatasource;
75 }
76
77
78
79
80 @Deprecated
81 public NodeNameFieldValidatorFactory(NodeNameValidatorDefinition definition, info.magnolia.ui.ValueContext<Item> valueContext, SimpleTranslator simpleTranslator, NodeNameHelper nodeNameHelper) {
82 this(definition, valueContext, simpleTranslator, nodeNameHelper, Components.getComponent(JcrDatasource.class));
83 }
84
85 @Override
86 public Validator<String> createValidator() {
87 return new RegexpValidator("Node name can't be empty", ".+") {
88 @Override
89 public ValidationResult apply(String value, ValueContext context) {
90 ValidationResult validationResult = super.apply(value, context);
91 if (validationResult.isError()) {
92 return validationResult;
93 }
94 Item item = valueContext.getSingle()
95 .orElseGet(jcrDatasource::getRoot);
96
97 return Optional.of(item)
98 .map(Exceptions.wrap().function(node -> definition.getMode() == NodeNameValidatorDefinition.Mode.ADD ? node : node.getParent()))
99 .map(Exceptions.wrap().function(Item::getPath))
100 .map(path -> StringUtils.appendIfMissing(path, "/"))
101 .map(path -> path + nodeNameHelper.getValidatedName(value))
102 .filter(Exceptions.wrap().predicate(path -> jcrDatasource.getJCRSession().itemExists(path)))
103 .map(Exceptions.wrap().function(path -> jcrDatasource.getJCRSession().getItem(path)))
104 .filter(Exceptions.wrap().predicate(sibling -> isFailure(sibling, item)))
105 .map(any -> getI18nErrorMessage(value))
106 .map(ValidationResult::error)
107 .orElse(validationResult);
108 }
109
110 private boolean isFailure(Item sibling, Item item) throws RepositoryException {
111 if (item.isNode() && sibling.isNode()) {
112 return !((Node) sibling).getIdentifier().equals(((Node) item).getIdentifier());
113 } else {
114 return !sibling.getName().equals(item.getName());
115 }
116 }
117
118 private String getI18nErrorMessage(String value) {
119 return simpleTranslator.translate("{0} already exists.", value);
120 }
121 };
122 }
123
124 }