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