1 package org.apache.maven.doxia.site.decoration.inheritance;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.apache.maven.doxia.site.decoration.Banner;
26 import org.apache.maven.doxia.site.decoration.Body;
27 import org.apache.maven.doxia.site.decoration.DecorationModel;
28 import org.apache.maven.doxia.site.decoration.LinkItem;
29 import org.apache.maven.doxia.site.decoration.Logo;
30 import org.apache.maven.doxia.site.decoration.Menu;
31 import org.apache.maven.doxia.site.decoration.MenuItem;
32
33 import org.codehaus.plexus.util.xml.Xpp3Dom;
34
35
36
37
38
39
40
41
42
43 public class DefaultDecorationModelInheritanceAssembler
44 implements DecorationModelInheritanceAssembler
45 {
46
47 public void assembleModelInheritance( String name, DecorationModel child, DecorationModel parent,
48 String childBaseUrl, String parentBaseUrl )
49 {
50
51 if ( parent == null )
52 {
53 return;
54 }
55
56 URLContainer urlContainer = new URLContainer( parentBaseUrl, childBaseUrl );
57
58 if ( child.getBannerLeft() == null && parent.getBannerLeft() != null )
59 {
60 child.setBannerLeft( parent.getBannerLeft().clone());
61 rebaseBannerPaths( child.getBannerLeft(), urlContainer );
62 }
63
64 if ( child.getBannerRight() == null && parent.getBannerRight() != null)
65 {
66 child.setBannerRight( parent.getBannerRight().clone());
67 rebaseBannerPaths( child.getBannerRight(), urlContainer );
68 }
69
70 if ( child.getPublishDate() == null && parent.getPublishDate() != null )
71 {
72 child.setPublishDate( parent.getPublishDate().clone());
73 }
74
75 if ( child.getVersion() == null && parent.getVersion() != null )
76 {
77 child.setVersion( parent.getVersion().clone());
78 }
79
80 if ( child.getSkin() == null && parent.getSkin() != null )
81 {
82 child.setSkin( parent.getSkin().clone());
83 }
84
85 child.setPoweredBy( mergePoweredByLists( child.getPoweredBy(), parent.getPoweredBy(), urlContainer ) );
86
87 if ( parent.getLastModified() > child.getLastModified() )
88 {
89 child.setLastModified( parent.getLastModified() );
90 }
91
92 assembleBodyInheritance( name, child, parent, urlContainer );
93
94 assembleCustomInheritance( child, parent );
95 }
96
97
98 public void resolvePaths( final DecorationModel decoration, final String baseUrl )
99 {
100 if ( baseUrl == null )
101 {
102 return;
103 }
104
105 if ( decoration.getBannerLeft() != null )
106 {
107 relativizeBannerPaths( decoration.getBannerLeft(), baseUrl );
108 }
109
110 if ( decoration.getBannerRight() != null )
111 {
112 relativizeBannerPaths( decoration.getBannerRight(), baseUrl );
113 }
114
115 for ( Logo logo : decoration.getPoweredBy() )
116 {
117 relativizeLogoPaths( logo, baseUrl );
118 }
119
120 if ( decoration.getBody() != null )
121 {
122 for ( LinkItem linkItem : decoration.getBody().getLinks() )
123 {
124 relativizeLinkItemPaths( linkItem, baseUrl );
125 }
126
127 for ( LinkItem linkItem : decoration.getBody().getBreadcrumbs() )
128 {
129 relativizeLinkItemPaths( linkItem, baseUrl );
130 }
131
132 for ( Menu menu : decoration.getBody().getMenus() )
133 {
134 relativizeMenuPaths( menu.getItems(), baseUrl );
135 }
136 }
137 }
138
139
140
141
142
143
144
145
146 private void relativizeBannerPaths( final Banner banner, final String baseUrl )
147 {
148
149 banner.setHref( relativizeLink( banner.getHref(), baseUrl ) );
150 banner.setSrc( relativizeLink( banner.getSrc(), baseUrl ) );
151 }
152
153 private void rebaseBannerPaths( final Banner banner, final URLContainer urlContainer )
154 {
155 if ( banner.getHref() != null )
156 {
157 banner.setHref( rebaseLink( banner.getHref(), urlContainer ) );
158 }
159
160 if ( banner.getSrc() != null )
161 {
162 banner.setSrc( rebaseLink( banner.getSrc(), urlContainer ) );
163 }
164 }
165
166 private void assembleCustomInheritance( final DecorationModel child, final DecorationModel parent )
167 {
168 if ( child.getCustom() == null )
169 {
170 child.setCustom( parent.getCustom() );
171 }
172 else
173 {
174 child.setCustom( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) child.getCustom(), (Xpp3Dom) parent.getCustom() ) );
175 }
176 }
177
178 private void assembleBodyInheritance( final String name, final DecorationModel child, final DecorationModel parent,
179 final URLContainer urlContainer )
180 {
181 Body cBody = child.getBody();
182 Body pBody = parent.getBody();
183
184 if ( cBody != null || pBody != null )
185 {
186 if ( cBody == null )
187 {
188 cBody = new Body();
189 child.setBody( cBody );
190 }
191
192 if ( pBody == null )
193 {
194 pBody = new Body();
195 }
196
197 if ( cBody.getHead() == null )
198 {
199 cBody.setHead( pBody.getHead() );
200 }
201 else
202 {
203 cBody.setHead( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) cBody.getHead(), (Xpp3Dom) pBody.getHead() ) );
204 }
205
206 cBody.setLinks( mergeLinkItemLists( cBody.getLinks(), pBody.getLinks(), urlContainer, false ) );
207
208 if ( cBody.getBreadcrumbs().isEmpty() && !pBody.getBreadcrumbs().isEmpty() )
209 {
210 LinkItem breadcrumb = new LinkItem();
211 breadcrumb.setName( name );
212 breadcrumb.setHref( "" );
213 cBody.getBreadcrumbs().add( breadcrumb );
214 }
215 cBody.setBreadcrumbs( mergeLinkItemLists( cBody.getBreadcrumbs(), pBody.getBreadcrumbs(), urlContainer,
216 true ) );
217
218 cBody.setMenus( mergeMenus( cBody.getMenus(), pBody.getMenus(), urlContainer ) );
219
220 if ( cBody.getFooter() == null && pBody.getFooter() != null )
221 {
222 cBody.setFooter( pBody.getFooter() );
223 }
224 }
225 }
226
227 private List<Menu> mergeMenus( final List<Menu> childMenus, final List<Menu> parentMenus,
228 final URLContainer urlContainer )
229 {
230 List<Menu> menus = new ArrayList<Menu>( childMenus.size() + parentMenus.size() );
231
232 for ( Menu menu : childMenus )
233 {
234 menus.add( menu );
235 }
236
237 int topCounter = 0;
238 for ( Menu menu : parentMenus )
239 {
240 if ( "top".equals( menu.getInherit() ) )
241 {
242 final Menu clone = menu.clone();
243
244 rebaseMenuPaths( clone.getItems(), urlContainer );
245
246 menus.add( topCounter, clone );
247 topCounter++;
248 }
249 else if ( "bottom".equals( menu.getInherit() ) )
250 {
251 final Menu clone = menu.clone();
252
253 rebaseMenuPaths( clone.getItems(), urlContainer );
254
255 menus.add( clone );
256 }
257 }
258
259 return menus;
260 }
261
262 private void relativizeMenuPaths( final List<MenuItem> items, final String baseUrl )
263 {
264 for ( MenuItem item : items )
265 {
266 relativizeLinkItemPaths( item, baseUrl );
267 relativizeMenuPaths( item.getItems(), baseUrl );
268 }
269 }
270
271 private void rebaseMenuPaths( final List<MenuItem> items, final URLContainer urlContainer )
272 {
273 for ( MenuItem item : items )
274 {
275 rebaseLinkItemPaths( item, urlContainer );
276 rebaseMenuPaths( item.getItems(), urlContainer );
277 }
278 }
279
280 private void relativizeLinkItemPaths( final LinkItem item, final String baseUrl )
281 {
282 item.setHref( relativizeLink( item.getHref(), baseUrl ) );
283 }
284
285 private void rebaseLinkItemPaths( final LinkItem item, final URLContainer urlContainer )
286 {
287 item.setHref( rebaseLink( item.getHref(), urlContainer ) );
288 }
289
290 private void relativizeLogoPaths( final Logo logo, final String baseUrl )
291 {
292 logo.setImg( relativizeLink( logo.getImg(), baseUrl ) );
293 relativizeLinkItemPaths( logo, baseUrl );
294 }
295
296 private void rebaseLogoPaths( final Logo logo, final URLContainer urlContainer )
297 {
298 logo.setImg( rebaseLink( logo.getImg(), urlContainer ) );
299 rebaseLinkItemPaths( logo, urlContainer );
300 }
301
302 private List<LinkItem> mergeLinkItemLists( final List<LinkItem> childList, final List<LinkItem> parentList,
303 final URLContainer urlContainer, boolean cutParentAfterDuplicate )
304 {
305 List<LinkItem> items = new ArrayList<LinkItem>( childList.size() + parentList.size() );
306
307 for ( LinkItem item : parentList )
308 {
309 if ( !items.contains( item ) && !childList.contains( item ) )
310 {
311 final LinkItem clone = item.clone();
312
313 rebaseLinkItemPaths( clone, urlContainer );
314
315 items.add( clone );
316 }
317 else if ( cutParentAfterDuplicate )
318 {
319
320
321
322 break;
323 }
324 }
325
326 for ( LinkItem item : childList )
327 {
328 if ( !items.contains( item ) )
329 {
330 items.add( item );
331 }
332 }
333
334 return items;
335 }
336
337 private List<Logo> mergePoweredByLists( final List<Logo> childList, final List<Logo> parentList,
338 final URLContainer urlContainer )
339 {
340 List<Logo> logos = new ArrayList<Logo>( childList.size() + parentList.size() );
341
342 for ( Logo logo : parentList )
343 {
344 if ( !logos.contains( logo ) )
345 {
346 final Logo clone = logo.clone();
347
348 rebaseLogoPaths( clone, urlContainer );
349
350 logos.add( clone );
351 }
352 }
353
354 for ( Logo logo : childList )
355 {
356 if ( !logos.contains( logo ) )
357 {
358 logos.add( logo );
359 }
360 }
361
362 return logos;
363 }
364
365
366
367 private String rebaseLink( final String link, final URLContainer urlContainer )
368 {
369 if ( link == null || urlContainer.getOldPath() == null )
370 {
371 return link;
372 }
373
374 final URIPathDescriptor oldPath = new URIPathDescriptor( urlContainer.getOldPath(), link );
375
376 return oldPath.rebaseLink( urlContainer.getNewPath() ).toString();
377 }
378
379
380
381 private String relativizeLink( final String link, final String baseUri )
382 {
383 if ( link == null || baseUri == null )
384 {
385 return link;
386 }
387
388
389 try
390 {
391 final URIPathDescriptor path = new URIPathDescriptor( baseUri, link );
392
393 return path.relativizeLink().toString();
394 }
395 catch ( IllegalArgumentException e )
396 {
397 return link;
398 }
399 }
400
401
402
403
404 public final class URLContainer
405 {
406
407 private final String oldPath;
408
409 private final String newPath;
410
411
412
413
414
415
416
417 public URLContainer( final String oldPath, final String newPath )
418 {
419 this.oldPath = oldPath;
420 this.newPath = newPath;
421 }
422
423
424
425
426
427
428 public String getNewPath()
429 {
430 return this.newPath;
431 }
432
433
434
435
436
437
438 public String getOldPath()
439 {
440 return this.oldPath;
441 }
442 }
443 }