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.jcr.util;
35
36 import info.magnolia.cms.util.SelectorUtil;
37 import info.magnolia.init.MagnoliaConfigurationProperties;
38
39 import java.nio.charset.StandardCharsets;
40
41 import javax.inject.Inject;
42 import javax.inject.Singleton;
43 import javax.jcr.Node;
44 import javax.jcr.RepositoryException;
45 import javax.jcr.Session;
46
47 import org.apache.commons.io.FilenameUtils;
48 import org.apache.commons.lang3.StringUtils;
49
50
51
52
53 @Singleton
54 public class NodeNameHelper {
55
56 private final String DEFAULT_UNTITLED_NODE_NAME = "untitled";
57
58 private final MagnoliaConfigurationProperties magnoliaConfigurationProperties;
59
60 @Inject
61 public NodeNameHelper(MagnoliaConfigurationProperties magnoliaConfigurationProperties) {
62 this.magnoliaConfigurationProperties = magnoliaConfigurationProperties;
63 }
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public String getUniqueName(Session session, String parentPath, String name) throws RepositoryException {
83 if (parentPath.equals("/")) {
84 parentPath = StringUtils.EMPTY;
85 }
86 while (session.itemExists(parentPath + "/" + name)) {
87 name = createUniqueName(name);
88 }
89 return name;
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public String getUniqueName(Session session, String parentPath, String name, String extension) throws RepositoryException {
111 if (StringUtils.isNotEmpty(extension) && extension.equals(FilenameUtils.getExtension(name))) {
112 parentPath = "/".equals(parentPath) ? StringUtils.EMPTY : parentPath;
113 String basename = FilenameUtils.getBaseName(name);
114 String fullName = name;
115
116 while (session.itemExists(parentPath + "/" + fullName)) {
117 basename = createUniqueName(basename);
118 fullName = basename + FilenameUtils.EXTENSION_SEPARATOR + extension;
119 }
120 return fullName;
121 }
122
123 return getUniqueName(session, parentPath, name);
124 }
125
126 public String getUniqueName(Node parent, String name) throws RepositoryException {
127 while (parent.hasNode(name) || parent.hasProperty(name)) {
128 name = createUniqueName(name);
129 }
130 return name;
131 }
132
133
134
135
136
137
138 public String getValidatedName(String name) {
139 String charset = StringUtils.EMPTY;
140 if (magnoliaConfigurationProperties.getBooleanProperty(MagnoliaConfigurationProperties.MAGNOLIA_UTF8_ENABLED)) {
141 charset = StandardCharsets.UTF_8.name();
142 }
143 return getValidatedName(name, charset);
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 public String getValidatedName(String name, String charset) {
160 if (StringUtils.isEmpty(name)) {
161 return DEFAULT_UNTITLED_NODE_NAME;
162 }
163 final StringBuilder newLabel = new StringBuilder(name.length());
164
165
166 int ch = name.charAt(0);
167 if (!isCharValid(ch, charset) || ch == 46) {
168 newLabel.append("-");
169 } else {
170 newLabel.append(name.charAt(0));
171 }
172
173 for (int i = 1; i < name.length(); i++) {
174 int charCode = name.charAt(i);
175 if (isCharValid(charCode, charset)) {
176 newLabel.append(name.charAt(i));
177 } else {
178 newLabel.append("-");
179 }
180 }
181 if (newLabel.length() == 0) {
182 newLabel.append(DEFAULT_UNTITLED_NODE_NAME);
183 }
184 return newLabel.toString();
185 }
186
187 private boolean isCharValid(int charCode, String charset) {
188
189
190
191
192
193
194
195
196
197
198
199 if (StandardCharsets.UTF_8.name().equals(charset)) {
200
201
202 if (charCode != 32
203 && charCode != '['
204 && charCode != ']'
205 && charCode != '*'
206 && charCode != '"'
207 && charCode != ':'
208 && charCode != 92
209 && charCode != 39
210 && charCode != ';'
211 && charCode != '/'
212 && charCode != '?'
213 && charCode != '+'
214 && charCode != '%'
215 && charCode != '!'
216 && charCode != '#'
217 && charCode != '@'
218 && charCode != '='
219 && charCode != '&'
220 && charCode != SelectorUtil.SELECTOR_DELIMITER.charAt(0)) {
221 return true;
222 }
223 } else {
224
225 if (((charCode >= 48) && (charCode <= 57))
226 || ((charCode >= 65) && (charCode <= 90))
227 || ((charCode >= 97) && (charCode <= 122))
228 || charCode == 45
229 || charCode == 46
230 || charCode == 95) {
231 return true;
232 }
233
234 }
235 return false;
236 }
237
238 private String createUniqueName(String baseName) {
239 int pos;
240 for (pos = baseName.length() - 1; pos >= 0; pos--) {
241 char c = baseName.charAt(pos);
242 if (c < '0' || c > '9') {
243 break;
244 }
245 }
246 String base;
247 int cnt;
248 if (pos == -1) {
249 if (baseName.length() > 1) {
250 pos = baseName.length() - 2;
251 }
252 }
253 if (pos == -1) {
254 base = baseName;
255 cnt = -1;
256 } else {
257 pos++;
258 base = baseName.substring(0, pos);
259 if (pos == baseName.length()) {
260 cnt = -1;
261 } else {
262 cnt = Integer.parseInt(baseName.substring(pos));
263 }
264 }
265 return (base + ++cnt);
266 }
267 }