%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.jetspeed.page.document.psml.AbstractNode |
|
|
1 | /* |
|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 | * contributor license agreements. See the NOTICE file distributed with |
|
4 | * this work for additional information regarding copyright ownership. |
|
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
6 | * (the "License"); you may not use this file except in compliance with |
|
7 | * the License. You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
16 | */ |
|
17 | package org.apache.jetspeed.page.document.psml; |
|
18 | ||
19 | import java.util.Collection; |
|
20 | import java.util.List; |
|
21 | import java.util.Locale; |
|
22 | ||
23 | import org.apache.jetspeed.JetspeedActions; |
|
24 | import org.apache.jetspeed.om.common.GenericMetadata; |
|
25 | import org.apache.jetspeed.om.common.SecurityConstraints; |
|
26 | import org.apache.jetspeed.om.page.PageMetadataImpl; |
|
27 | import org.apache.jetspeed.om.page.PageSecurity; |
|
28 | import org.apache.jetspeed.om.page.psml.AbstractBaseElement; |
|
29 | import org.apache.jetspeed.om.page.psml.SecurityConstraintsImpl; |
|
30 | import org.apache.jetspeed.page.document.Node; |
|
31 | ||
32 | ||
33 | /** |
|
34 | * <p> |
|
35 | * AbstractNode |
|
36 | * </p> |
|
37 | * <p> |
|
38 | * |
|
39 | * </p> |
|
40 | * |
|
41 | * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a> |
|
42 | * @version $Id: AbstractNode.java 551606 2007-06-28 16:07:53Z taylor $ |
|
43 | * |
|
44 | */ |
|
45 | public abstract class AbstractNode extends AbstractBaseElement implements Node |
|
46 | { |
|
47 | private PageMetadataImpl metadata; |
|
48 | private Node parent; |
|
49 | private String path; |
|
50 | private String url; |
|
51 | 0 | private boolean hidden=false; |
52 | private String profiledPath; |
|
53 | 0 | private boolean dirty=false; |
54 | ||
55 | public AbstractNode() |
|
56 | 0 | { |
57 | 0 | } |
58 | ||
59 | /** |
|
60 | * getMetadata - get/construct metadata |
|
61 | * |
|
62 | * @return metadata |
|
63 | */ |
|
64 | public GenericMetadata getMetadata() |
|
65 | { |
|
66 | 0 | return getPageMetadata(); |
67 | } |
|
68 | ||
69 | /** |
|
70 | * setMetadata - set metadata fields |
|
71 | * |
|
72 | * @param metadata metadata |
|
73 | */ |
|
74 | public void setMetadata(GenericMetadata metadata) |
|
75 | { |
|
76 | 0 | getPageMetadata().setFields(metadata.getFields()); |
77 | 0 | } |
78 | ||
79 | /** |
|
80 | * getMetadataFields - get metadata fields collection for |
|
81 | * marshalling/unmarshalling |
|
82 | * |
|
83 | * @return metadata fields collection |
|
84 | */ |
|
85 | public Collection getMetadataFields() |
|
86 | { |
|
87 | // return metadata fields collection that |
|
88 | // may in fact be side effected on unmarshall |
|
89 | 0 | return getPageMetadata().getFields(); |
90 | } |
|
91 | ||
92 | /** |
|
93 | * setMetadataFields - set metadata fields collection |
|
94 | * |
|
95 | * @param metadataFields metadata fields collection |
|
96 | */ |
|
97 | public void setMetadataFields(Collection metadataFields) |
|
98 | { |
|
99 | // set metadata fields collection that |
|
100 | // may in fact be side effected after |
|
101 | // invocation on unmarshall |
|
102 | 0 | getPageMetadata().setFields(metadataFields); |
103 | 0 | } |
104 | ||
105 | /** |
|
106 | * getPageMetadata - get/construct page metadata instance |
|
107 | * |
|
108 | * @return metadata instance |
|
109 | */ |
|
110 | private PageMetadataImpl getPageMetadata() |
|
111 | { |
|
112 | 0 | if (metadata == null) |
113 | { |
|
114 | 0 | metadata = new PageMetadataImpl(); |
115 | } |
|
116 | 0 | return metadata; |
117 | } |
|
118 | ||
119 | /** |
|
120 | * <p> |
|
121 | * getTitle |
|
122 | * </p> |
|
123 | * |
|
124 | * @see org.apache.jetspeed.page.document.Node#getTitle(java.util.Locale) |
|
125 | * @param locale |
|
126 | * @return title in specified locale |
|
127 | */ |
|
128 | public String getTitle(Locale locale) |
|
129 | { |
|
130 | // get title from metadata or use default title |
|
131 | 0 | String title = getPageMetadata().getText("title", locale); |
132 | 0 | if (title == null) |
133 | { |
|
134 | 0 | title = getTitle(); |
135 | } |
|
136 | 0 | return title; |
137 | } |
|
138 | ||
139 | /** |
|
140 | * <p> |
|
141 | * getShortTitle |
|
142 | * </p> |
|
143 | * |
|
144 | * @see org.apache.jetspeed.page.document.Node#getShortTitle(java.util.Locale) |
|
145 | * @param locale |
|
146 | * @return short title in specified locale |
|
147 | */ |
|
148 | public String getShortTitle( Locale locale ) |
|
149 | { |
|
150 | // get short title from metadata or use title from metadata, |
|
151 | // default short title, or default title |
|
152 | 0 | String shortTitle = getPageMetadata().getText("short-title", locale); |
153 | 0 | if (shortTitle == null) |
154 | { |
|
155 | 0 | shortTitle = getPageMetadata().getText("title", locale); |
156 | 0 | if (shortTitle == null) |
157 | { |
|
158 | 0 | shortTitle = getShortTitle(); |
159 | 0 | if (shortTitle == null) |
160 | { |
|
161 | 0 | shortTitle = getTitle(); |
162 | } |
|
163 | } |
|
164 | } |
|
165 | 0 | return shortTitle; |
166 | } |
|
167 | ||
168 | /** |
|
169 | * <p> |
|
170 | * getParent |
|
171 | * </p> |
|
172 | * |
|
173 | * @param checkAccess flag |
|
174 | * @return parent node |
|
175 | */ |
|
176 | public Node getParent(boolean checkAccess) |
|
177 | { |
|
178 | 0 | AbstractNode parent = (AbstractNode) this.parent; |
179 | ||
180 | // check access |
|
181 | 0 | if ((parent != null) && checkAccess) |
182 | { |
|
183 | 0 | parent.checkAccess(JetspeedActions.VIEW); |
184 | } |
|
185 | 0 | return parent; |
186 | } |
|
187 | ||
188 | /** |
|
189 | * <p> |
|
190 | * getParent |
|
191 | * </p> |
|
192 | * |
|
193 | * @see org.apache.jetspeed.page.document.Node#getParent() |
|
194 | * @return parent node |
|
195 | */ |
|
196 | public Node getParent() |
|
197 | { |
|
198 | // by default disable access checks since it is assumed |
|
199 | // that by accessing this node, access to parent must |
|
200 | // also be granted |
|
201 | 0 | return getParent(false); |
202 | } |
|
203 | ||
204 | /** |
|
205 | * <p> |
|
206 | * setParent |
|
207 | * </p> |
|
208 | * |
|
209 | * @see org.apache.jetspeed.page.document.Node#setParent(Node) |
|
210 | * @param parent |
|
211 | */ |
|
212 | public void setParent( Node parent ) |
|
213 | { |
|
214 | 0 | this.parent = parent; |
215 | 0 | } |
216 | ||
217 | /** |
|
218 | * <p> |
|
219 | * getName |
|
220 | * </p> |
|
221 | * |
|
222 | * @see org.apache.jetspeed.page.document.Node#getName() |
|
223 | * @return Name |
|
224 | */ |
|
225 | public String getName() |
|
226 | { |
|
227 | // simply strip path to determine name |
|
228 | 0 | String name = getPath(); |
229 | 0 | if ((name != null) && !name.equals(PATH_SEPARATOR)) |
230 | { |
|
231 | 0 | if (name.endsWith(PATH_SEPARATOR)) |
232 | { |
|
233 | 0 | name = name.substring(0, name.length()-1); |
234 | } |
|
235 | 0 | name = name.substring(name.lastIndexOf(PATH_SEPARATOR)+1); |
236 | } |
|
237 | 0 | return name; |
238 | } |
|
239 | ||
240 | /** |
|
241 | * getTitleName - get name for use as default titles |
|
242 | * |
|
243 | * @return title name |
|
244 | */ |
|
245 | public String getTitleName() |
|
246 | { |
|
247 | 0 | String titleName = getName(); |
248 | 0 | if (titleName != null) |
249 | { |
|
250 | // transform file system name to title |
|
251 | 0 | if (titleName.endsWith(getType())) |
252 | { |
|
253 | 0 | titleName = titleName.substring(0, titleName.length()-getType().length()); |
254 | } |
|
255 | 0 | else if (titleName.equals(PATH_SEPARATOR)) |
256 | { |
|
257 | 0 | titleName = "top"; |
258 | } |
|
259 | 0 | titleName = titleName.replace('_', ' '); |
260 | 0 | titleName = titleName.replace('-', ' '); |
261 | 0 | int wordIndex = -1; |
262 | do |
|
263 | { |
|
264 | 0 | if (!Character.isTitleCase(titleName.charAt(wordIndex+1))) |
265 | { |
|
266 | 0 | StringBuffer makeTitle = new StringBuffer(); |
267 | 0 | makeTitle.append(titleName.substring(0, wordIndex+1)); |
268 | 0 | makeTitle.append(Character.toTitleCase(titleName.charAt(wordIndex+1))); |
269 | 0 | makeTitle.append(titleName.substring(wordIndex+2)); |
270 | 0 | titleName = makeTitle.toString(); |
271 | } |
|
272 | 0 | wordIndex = titleName.indexOf(' ', wordIndex+1); |
273 | } |
|
274 | 0 | while (wordIndex != -1); |
275 | } |
|
276 | 0 | return titleName; |
277 | } |
|
278 | ||
279 | /** |
|
280 | * @return Returns the path. |
|
281 | */ |
|
282 | public String getPath() |
|
283 | { |
|
284 | 0 | return path; |
285 | } |
|
286 | ||
287 | /** |
|
288 | * <p> |
|
289 | * setPath |
|
290 | * </p> |
|
291 | * |
|
292 | * @param path The path to set. |
|
293 | */ |
|
294 | public void setPath( String path ) |
|
295 | { |
|
296 | // PSML id is always kept in sync with path, despite how the |
|
297 | // id may be loaded from the persistent store |
|
298 | 0 | this.path = path; |
299 | 0 | setId(path); |
300 | 0 | } |
301 | ||
302 | /** |
|
303 | * <p> |
|
304 | * getUrl |
|
305 | * </p> |
|
306 | * Same as invoking <code>Node.getPath()</code> unless url explicitly set. |
|
307 | * |
|
308 | * @see org.apache.jetspeed.page.document.Node#getUrl() |
|
309 | * @return url as string |
|
310 | */ |
|
311 | public String getUrl() |
|
312 | { |
|
313 | 0 | if (url != null) |
314 | { |
|
315 | 0 | return url; |
316 | } |
|
317 | 0 | return getPath(); |
318 | } |
|
319 | ||
320 | /** |
|
321 | * <p> |
|
322 | * setUrl |
|
323 | * </p> |
|
324 | * |
|
325 | * @param url The url to set. |
|
326 | */ |
|
327 | public void setUrl( String url ) |
|
328 | { |
|
329 | 0 | this.url = url; |
330 | 0 | } |
331 | ||
332 | /** |
|
333 | * <p> |
|
334 | * isHidden |
|
335 | * </p> |
|
336 | * |
|
337 | * @see org.apache.jetspeed.page.document.Node#isHidden() |
|
338 | * @return hidden |
|
339 | */ |
|
340 | public boolean isHidden() |
|
341 | { |
|
342 | 0 | return hidden; |
343 | } |
|
344 | /** |
|
345 | * @param hidden The hidden to set. |
|
346 | */ |
|
347 | public void setHidden( boolean hidden ) |
|
348 | { |
|
349 | 0 | this.hidden = hidden; |
350 | 0 | } |
351 | ||
352 | /** |
|
353 | * @return Returns the profiled path. |
|
354 | */ |
|
355 | public String getProfiledPath() |
|
356 | { |
|
357 | 0 | return profiledPath; |
358 | } |
|
359 | /** |
|
360 | * @param profiledPath The profiled path to set. |
|
361 | */ |
|
362 | public void setProfiledPath( String profiledPath ) |
|
363 | { |
|
364 | 0 | this.profiledPath = profiledPath; |
365 | 0 | } |
366 | ||
367 | /** |
|
368 | * getEffectivePageSecurity |
|
369 | * |
|
370 | * @see org.apache.jetspeed.om.page.psml.AbstractBaseElement#getEffectivePageSecurity() |
|
371 | */ |
|
372 | public PageSecurity getEffectivePageSecurity() |
|
373 | { |
|
374 | // by default, delegate to parent node implementation |
|
375 | 0 | if (parent != null) |
376 | { |
|
377 | 0 | return ((AbstractNode)parent).getEffectivePageSecurity(); |
378 | } |
|
379 | 0 | return null; |
380 | } |
|
381 | ||
382 | /** |
|
383 | * <p> |
|
384 | * checkConstraints |
|
385 | * </p> |
|
386 | * |
|
387 | * @param actions |
|
388 | * @param userPrincipals |
|
389 | * @param rolePrincipals |
|
390 | * @param groupPrincipals |
|
391 | * @param checkNodeOnly |
|
392 | * @param checkParentsOnly |
|
393 | * @throws SecurityException |
|
394 | */ |
|
395 | public void checkConstraints(List actions, List userPrincipals, List rolePrincipals, List groupPrincipals, boolean checkNodeOnly, class="keyword">boolean checkParentsOnly) throws SecurityException |
|
396 | { |
|
397 | // check constraints in node hierarchy |
|
398 | 0 | if (checkNodeOnly) |
399 | { |
|
400 | // check node constraints if available; otherwise, |
|
401 | // recursively check parent constraints until |
|
402 | // default constraints for node are checked |
|
403 | 0 | SecurityConstraints constraints = getSecurityConstraints(); |
404 | 0 | if ((constraints != null) && !constraints.isEmpty()) |
405 | { |
|
406 | 0 | ((SecurityConstraintsImpl)constraints).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity()); |
407 | } |
|
408 | 0 | else if (parent != null) |
409 | { |
|
410 | 0 | ((AbstractNode)parent).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, checkNodeOnly, false); |
411 | } |
|
412 | 0 | } |
413 | else |
|
414 | { |
|
415 | // check node constraints if available and not |
|
416 | // to be skipped due to explicity granted access |
|
417 | 0 | if (!checkParentsOnly) |
418 | { |
|
419 | 0 | SecurityConstraints constraints = getSecurityConstraints(); |
420 | 0 | if ((constraints != null) && !constraints.isEmpty()) |
421 | { |
|
422 | 0 | ((SecurityConstraintsImpl)constraints).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity()); |
423 | } |
|
424 | } |
|
425 | ||
426 | // recursively check all parent constraints in hierarchy |
|
427 | 0 | if (parent != null) |
428 | { |
|
429 | 0 | ((AbstractNode)parent).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, false, false); |
430 | } |
|
431 | } |
|
432 | 0 | } |
433 | ||
434 | /** |
|
435 | * <p> |
|
436 | * checkPermissions |
|
437 | * </p> |
|
438 | * |
|
439 | * @param path |
|
440 | * @param mask Mask of actions requested |
|
441 | * @param checkNodeOnly |
|
442 | * @param checkParentsOnly |
|
443 | * @throws SecurityException |
|
444 | */ |
|
445 | public void checkPermissions(String path, int mask, boolean checkNodeOnly, class="keyword">boolean checkParentsOnly) throws SecurityException |
|
446 | { |
|
447 | // check granted node permissions unless the check is |
|
448 | // to be skipped due to explicity granted access |
|
449 | 0 | if (!checkParentsOnly) |
450 | { |
|
451 | 0 | super.checkPermissions(path, mask, true, false); |
452 | } |
|
453 | ||
454 | // if not checking node only, recursively check |
|
455 | // all parent permissions in hierarchy |
|
456 | 0 | if (!checkNodeOnly && (parent != null)) |
457 | { |
|
458 | 0 | ((AbstractNode)parent).checkPermissions(mask, false, false); |
459 | } |
|
460 | 0 | } |
461 | ||
462 | /** |
|
463 | * <p> |
|
464 | * getLogicalPermissionPath |
|
465 | * </p> |
|
466 | * |
|
467 | * @return path used for permissions checks |
|
468 | */ |
|
469 | public String getLogicalPermissionPath() |
|
470 | { |
|
471 | 0 | return profiledPath; |
472 | } |
|
473 | ||
474 | /** |
|
475 | * <p> |
|
476 | * getPhysicalPermissionPath |
|
477 | * </p> |
|
478 | * |
|
479 | * @return path used for permissions checks |
|
480 | */ |
|
481 | public String getPhysicalPermissionPath() |
|
482 | { |
|
483 | 0 | return path; |
484 | } |
|
485 | ||
486 | /** |
|
487 | * unmarshalled - notification that this instance has been |
|
488 | * loaded from the persistent store |
|
489 | */ |
|
490 | public void unmarshalled() |
|
491 | { |
|
492 | // notify super class implementation |
|
493 | 0 | super.unmarshalled(); |
494 | ||
495 | // force metadata update after unmarshalled since |
|
496 | // metadata collection can be side effected by |
|
497 | // unmarshalling colection accessors |
|
498 | 0 | Collection metadataFields = getMetadataFields(); |
499 | 0 | if (metadataFields != null) |
500 | { |
|
501 | 0 | setMetadataFields(metadataFields); |
502 | } |
|
503 | 0 | } |
504 | ||
505 | public boolean isDirty() { |
|
506 | 0 | return dirty; |
507 | } |
|
508 | ||
509 | public void setDirty(boolean dirty) { |
|
510 | 0 | this.dirty=dirty; |
511 | 0 | } |
512 | ||
513 | ||
514 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |