1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.page.document.impl;
18
19 import java.util.Collection;
20 import java.util.List;
21 import java.util.Locale;
22 import java.util.StringTokenizer;
23
24 import org.apache.jetspeed.om.common.GenericMetadata;
25 import org.apache.jetspeed.om.folder.Folder;
26 import org.apache.jetspeed.om.page.PageMetadataImpl;
27 import org.apache.jetspeed.om.page.PageSecurity;
28 import org.apache.jetspeed.om.page.impl.BaseElementImpl;
29 import org.apache.jetspeed.om.page.impl.SecurityConstraintsImpl;
30 import org.apache.jetspeed.page.document.Node;
31 import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
32 import org.apache.ojb.broker.core.proxy.ProxyHelper;
33
34 /***
35 * NodeImpl
36 *
37 * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
38 * @version $Id$
39 */
40 public abstract class NodeImpl extends BaseElementImpl implements Node
41 {
42 private Node parent;
43 private boolean hidden;
44 private Collection metadataFields;
45 private String path = Folder.PATH_SEPARATOR;
46 private String subsite;
47 private String user;
48 private String role;
49 private String group;
50 private String mediatype;
51 private String locale;
52 private String extendedAttributeName;
53 private String extendedAttributeValue;
54
55 private PageMetadataImpl pageMetadata;
56 private String logicalPath;
57
58 public NodeImpl(SecurityConstraintsImpl constraints)
59 {
60 super(constraints);
61 }
62
63 /***
64 * getCanonicalNodePath
65 *
66 * Format paths used to set and query NodeImpl instances.
67 *
68 * @param path specified path
69 * @return canonical path
70 */
71 public static String getCanonicalNodePath(String path)
72 {
73
74 if ((path == null) || (path.length() == 0))
75 {
76 path = Folder.PATH_SEPARATOR;
77 }
78 if (!path.startsWith(Folder.PATH_SEPARATOR))
79 {
80 path = Folder.PATH_SEPARATOR + path;
81 }
82 if (path.endsWith(Folder.PATH_SEPARATOR) && !path.equals(Folder.PATH_SEPARATOR))
83 {
84 path = path.substring(0, path.length() - 1);
85 }
86 return path;
87 }
88
89 /***
90 * newPageMetadata
91 *
92 * Construct page manager specific metadata implementation.
93 *
94 * @param fields mutable fields collection
95 * @return page metadata
96 */
97 public PageMetadataImpl newPageMetadata(Collection fields)
98 {
99
100 return null;
101 }
102
103 /***
104 * getPageMetadata
105 *
106 * Get page manager specific metadata implementation.
107 *
108 * @return page metadata
109 */
110 public PageMetadataImpl getPageMetadata()
111 {
112 if (pageMetadata == null)
113 {
114 if (metadataFields == null)
115 {
116 metadataFields = DatabasePageManagerUtils.createList();
117 }
118 pageMetadata = newPageMetadata(metadataFields);
119 }
120 return pageMetadata;
121 }
122
123 /***
124 * defaultTitleFromName
125 *
126 * Compute default title from name.
127 *
128 * @return default title
129 */
130 protected String defaultTitleFromName()
131 {
132
133 String title = getName();
134 if (title != null)
135 {
136
137 if ((getType() != null) && title.endsWith(getType()))
138 {
139 title = title.substring(0, title.length()-getType().length());
140 }
141 else if (title.equals(Folder.PATH_SEPARATOR))
142 {
143 title = "top";
144 }
145
146 title = title.replace('_', ' ');
147 title = title.replace('-', ' ');
148
149 int wordIndex = -1;
150 do
151 {
152 if (!Character.isTitleCase(title.charAt(wordIndex+1)))
153 {
154 StringBuffer makeTitle = new StringBuffer();
155 makeTitle.append(title.substring(0, wordIndex+1));
156 makeTitle.append(Character.toTitleCase(title.charAt(wordIndex+1)));
157 makeTitle.append(title.substring(wordIndex+2));
158 title = makeTitle.toString();
159 }
160 wordIndex = title.indexOf(' ', wordIndex+1);
161 }
162 while (wordIndex != -1);
163 }
164 return title;
165 }
166
167
168
169
170 public String getName()
171 {
172
173 String name = super.getName();
174 if (name == null)
175 {
176 if (path != null)
177 {
178 if (!path.equals(Folder.PATH_SEPARATOR))
179 {
180 name = path.substring(path.lastIndexOf(Folder.PATH_SEPARATOR) + 1);
181 }
182 else
183 {
184 name = Folder.PATH_SEPARATOR;
185 }
186 super.setName(name);
187 }
188 }
189 return name;
190 }
191
192
193
194
195 public void setName(String name)
196 {
197
198 if (name != null)
199 {
200 if (path != null)
201 {
202
203 if (!name.equals(Folder.PATH_SEPARATOR))
204 {
205 path = path.substring(0, path.lastIndexOf(Folder.PATH_SEPARATOR) + 1) + name;
206 }
207 else
208 {
209 path = Folder.PATH_SEPARATOR;
210 }
211
212
213 logicalPath = null;
214 }
215 super.setName(name);
216 }
217 }
218
219
220
221
222 public PageSecurity getEffectivePageSecurity()
223 {
224
225 NodeImpl parentNodeImpl = (NodeImpl)ProxyHelper.getRealObject(parent);
226 if (parentNodeImpl != null)
227 {
228 return parentNodeImpl.getEffectivePageSecurity();
229 }
230 return null;
231 }
232
233
234
235
236 public void checkConstraints(List actions, List userPrincipals, List rolePrincipals, List groupPrincipals, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
237 {
238
239 if (checkNodeOnly)
240 {
241
242
243
244 SecurityConstraintsImpl constraintsImpl = (SecurityConstraintsImpl)getSecurityConstraints();
245 if ((constraintsImpl != null) && !constraintsImpl.isEmpty())
246 {
247 constraintsImpl.checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity());
248 }
249 else
250 {
251 NodeImpl parentNodeImpl = (NodeImpl)ProxyHelper.getRealObject(parent);
252 if (parentNodeImpl != null)
253 {
254 parentNodeImpl.checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, checkNodeOnly, false);
255 }
256 }
257 }
258 else
259 {
260
261
262 if (!checkParentsOnly)
263 {
264 SecurityConstraintsImpl constraintsImpl = (SecurityConstraintsImpl)getSecurityConstraints();
265 if ((constraintsImpl != null) && !constraintsImpl.isEmpty())
266 {
267 constraintsImpl.checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity());
268 }
269 }
270
271
272 NodeImpl parentNodeImpl = (NodeImpl)ProxyHelper.getRealObject(parent);
273 if (parentNodeImpl != null)
274 {
275 parentNodeImpl.checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, false, false);
276 }
277 }
278 }
279
280
281
282
283 public void checkPermissions(String path, int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
284 {
285
286
287 if (!checkParentsOnly)
288 {
289 super.checkPermissions(path, mask, true, false);
290 }
291
292
293
294 if (!checkNodeOnly)
295 {
296 NodeImpl parentNodeImpl = (NodeImpl)ProxyHelper.getRealObject(parent);
297 if (parentNodeImpl != null)
298 {
299 parentNodeImpl.checkPermissions(mask, false, false);
300 }
301 }
302 }
303
304
305
306
307 public String getLogicalPermissionPath()
308 {
309
310 if (logicalPath == null)
311 {
312
313 if ((subsite != null) || (user != null) || (role != null) || (group != null) || (mediatype != null) ||
314 (locale != null) || (extendedAttributeName != null) || (extendedAttributeValue != null))
315 {
316
317 boolean skipAttribute = false;
318 StringBuffer logicalPathBuffer = new StringBuffer();
319 StringTokenizer pathElements = new StringTokenizer(path, Folder.PATH_SEPARATOR);
320 while (pathElements.hasMoreTokens())
321 {
322
323 String pathElement = pathElements.nextToken();
324 if (!skipAttribute)
325 {
326 if (!pathElement.startsWith(Folder.RESERVED_SUBSITE_FOLDER_PREFIX))
327 {
328 if (!pathElement.startsWith(Folder.RESERVED_FOLDER_PREFIX))
329 {
330
331 logicalPathBuffer.append(Folder.PATH_SEPARATOR);
332 logicalPathBuffer.append(pathElement);
333 }
334 else
335 {
336
337 skipAttribute = true;
338 }
339 }
340 }
341 else
342 {
343
344 skipAttribute = false;
345 }
346 }
347
348
349 if (logicalPathBuffer.length() > 0)
350 {
351 logicalPath = logicalPathBuffer.toString();
352 }
353 else
354 {
355 logicalPath = Folder.PATH_SEPARATOR;
356 }
357 }
358 else
359 {
360
361 logicalPath = path;
362 }
363 }
364
365 return logicalPath;
366 }
367
368
369
370
371 public String getPhysicalPermissionPath()
372 {
373
374 return path;
375 }
376
377
378
379
380 public Node getParent()
381 {
382 return parent;
383 }
384
385
386
387
388 public void setParent(Node parent)
389 {
390
391 this.parent = parent;
392
393
394 if (parent != null)
395 {
396 String parentPath = parent.getPath();
397 if ((parentPath.equals(Folder.PATH_SEPARATOR) &&
398 (path.lastIndexOf(Folder.PATH_SEPARATOR) > 0)) ||
399 (!parentPath.equals(Folder.PATH_SEPARATOR) &&
400 !parentPath.equals(path.substring(0, path.lastIndexOf(Folder.PATH_SEPARATOR)))))
401 {
402
403 path = parentPath + Folder.PATH_SEPARATOR + getName();
404
405
406 logicalPath = null;
407 }
408 }
409 }
410
411
412
413
414 public String getPath()
415 {
416
417 return path;
418 }
419
420
421
422
423 public void setPath(String path)
424 {
425
426 this.path = getCanonicalNodePath(path);
427
428
429 logicalPath = null;
430
431
432 String attributeName = null;
433 StringTokenizer pathElements = new StringTokenizer(this.path, Folder.PATH_SEPARATOR);
434 while (pathElements.hasMoreTokens())
435 {
436 String pathElement = pathElements.nextToken();
437 if (attributeName != null)
438 {
439
440 if (attributeName.startsWith(Folder.RESERVED_USER_FOLDER_NAME))
441 {
442 user = pathElement.toLowerCase();
443 }
444 else if (attributeName.startsWith(Folder.RESERVED_ROLE_FOLDER_NAME))
445 {
446 role = pathElement.toLowerCase();
447 }
448 else if (attributeName.startsWith(Folder.RESERVED_GROUP_FOLDER_NAME))
449 {
450 group = pathElement.toLowerCase();
451 }
452 else if (attributeName.startsWith(Folder.RESERVED_MEDIATYPE_FOLDER_NAME))
453 {
454 mediatype = pathElement.toLowerCase();
455 }
456 else if (attributeName.startsWith(Folder.RESERVED_LANGUAGE_FOLDER_NAME))
457 {
458 if (locale != null)
459 {
460
461 locale = pathElement.toLowerCase() + "_" + locale;
462 }
463 else
464 {
465 locale = pathElement.toLowerCase();
466 }
467 }
468 else if (attributeName.startsWith(Folder.RESERVED_COUNTRY_FOLDER_NAME))
469 {
470 if (locale != null)
471 {
472
473 locale = locale + "_" + pathElement.toLowerCase() ;
474 }
475 else
476 {
477 locale = pathElement.toLowerCase();
478 }
479 }
480 else if (attributeName.startsWith(Folder.RESERVED_FOLDER_PREFIX))
481 {
482 extendedAttributeName = attributeName.substring(Folder.RESERVED_FOLDER_PREFIX.length());
483 extendedAttributeValue = pathElement.toLowerCase();
484 }
485
486
487 attributeName = null;
488 }
489 else if (pathElement.startsWith(Folder.RESERVED_SUBSITE_FOLDER_PREFIX))
490 {
491 subsite = pathElement.substring(Folder.RESERVED_SUBSITE_FOLDER_PREFIX.length()).toLowerCase();
492 }
493 else if (pathElement.startsWith(Folder.RESERVED_FOLDER_PREFIX))
494 {
495
496 attributeName = pathElement.toLowerCase();
497 }
498 }
499
500
501 if (!this.path.equals(Folder.PATH_SEPARATOR))
502 {
503 super.setName(this.path.substring(this.path.lastIndexOf(Folder.PATH_SEPARATOR) + 1));
504 }
505 else
506 {
507 super.setName(Folder.PATH_SEPARATOR);
508 }
509
510
511 if (parent != null)
512 {
513 String parentPath = parent.getPath();
514 if ((parentPath.equals(Folder.PATH_SEPARATOR) &&
515 (this.path.lastIndexOf(Folder.PATH_SEPARATOR) > 0)) ||
516 (!parentPath.equals(Folder.PATH_SEPARATOR) &&
517 !parentPath.equals(this.path.substring(0, this.path.lastIndexOf(Folder.PATH_SEPARATOR)))))
518 {
519 parent = null;
520 }
521 }
522 }
523
524
525
526
527 public GenericMetadata getMetadata()
528 {
529 return getPageMetadata();
530 }
531
532
533
534
535 public String getTitle(Locale locale)
536 {
537
538 String title = getPageMetadata().getText("title", locale);
539 if (title == null)
540 {
541 title = getTitle();
542 }
543 return title;
544 }
545
546
547
548
549 public String getShortTitle(Locale locale)
550 {
551
552
553 String shortTitle = getPageMetadata().getText("short-title", locale);
554 if (shortTitle == null)
555 {
556 shortTitle = getPageMetadata().getText("title", locale);
557 if (shortTitle == null)
558 {
559 shortTitle = getShortTitle();
560 if (shortTitle == null)
561 {
562 shortTitle = getTitle();
563 }
564 }
565 }
566 return shortTitle;
567 }
568
569
570
571
572 public abstract String getType();
573
574
575
576
577 public String getUrl()
578 {
579 return path;
580 }
581
582
583
584
585 public boolean isHidden()
586 {
587 return hidden;
588 }
589
590
591
592
593 public void setHidden(boolean hidden)
594 {
595 this.hidden = hidden;
596 }
597 }