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( rebaseLink( banner.getHref(), urlContainer ) );
175 }
176
177 if ( banner.getSrc() != null )
178 {
179 banner.setSrc( rebaseLink( banner.getSrc(), urlContainer ) );
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 )
215 {
216 cBody.setHead( pBody.getHead() );
217 }
218 else
219 {
220 cBody.setHead( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) cBody.getHead(), (Xpp3Dom) pBody.getHead() ) );
221 }
222
223 cBody.setLinks( mergeLinkItemLists( cBody.getLinks(), pBody.getLinks(), urlContainer, false ) );
224
225 if ( cBody.getBreadcrumbs().isEmpty() && !pBody.getBreadcrumbs().isEmpty() )
226 {
227 LinkItem breadcrumb = new LinkItem();
228 breadcrumb.setName( name );
229 breadcrumb.setHref( "" );
230 cBody.getBreadcrumbs().add( breadcrumb );
231 }
232 cBody.setBreadcrumbs( mergeLinkItemLists( cBody.getBreadcrumbs(), pBody.getBreadcrumbs(), urlContainer,
233 true ) );
234
235 cBody.setMenus( mergeMenus( cBody.getMenus(), pBody.getMenus(), urlContainer ) );
236
237 if ( cBody.getFooter() == null && pBody.getFooter() != null )
238 {
239 cBody.setFooter( pBody.getFooter() );
240 }
241 }
242 }
243
244 private List<Menu> mergeMenus( final List<Menu> childMenus, final List<Menu> parentMenus,
245 final URLContainer urlContainer )
246 {
247 List<Menu> menus = new ArrayList<Menu>( childMenus.size() + parentMenus.size() );
248
249 for ( Menu menu : childMenus )
250 {
251 menus.add( menu );
252 }
253
254 int topCounter = 0;
255 for ( Menu menu : parentMenus )
256 {
257 if ( "top".equals( menu.getInherit() ) )
258 {
259 final Menu clone = menu.clone();
260
261 rebaseMenuPaths( clone.getItems(), urlContainer );
262
263 menus.add( topCounter, clone );
264 topCounter++;
265 }
266 else if ( "bottom".equals( menu.getInherit() ) )
267 {
268 final Menu clone = menu.clone();
269
270 rebaseMenuPaths( clone.getItems(), urlContainer );
271
272 menus.add( clone );
273 }
274 }
275
276 return menus;
277 }
278
279 private void relativizeMenuPaths( final List<MenuItem> items, final String baseUrl )
280 {
281 for ( MenuItem item : items )
282 {
283 relativizeLinkItemPaths( item, baseUrl );
284 relativizeMenuPaths( item.getItems(), baseUrl );
285 }
286 }
287
288 private void rebaseMenuPaths( final List<MenuItem> items, final URLContainer urlContainer )
289 {
290 for ( MenuItem item : items )
291 {
292 rebaseLinkItemPaths( item, urlContainer );
293 rebaseMenuPaths( item.getItems(), urlContainer );
294 }
295 }
296
297 private void relativizeLinkItemPaths( final LinkItem item, final String baseUrl )
298 {
299 item.setHref( relativizeLink( item.getHref(), baseUrl ) );
300 }
301
302 private void rebaseLinkItemPaths( final LinkItem item, final URLContainer urlContainer )
303 {
304 item.setHref( rebaseLink( item.getHref(), urlContainer ) );
305 }
306
307 private void relativizeLogoPaths( final Logo logo, final String baseUrl )
308 {
309 logo.setImg( relativizeLink( logo.getImg(), baseUrl ) );
310 relativizeLinkItemPaths( logo, baseUrl );
311 }
312
313 private void rebaseLogoPaths( final Logo logo, final URLContainer urlContainer )
314 {
315 logo.setImg( rebaseLink( logo.getImg(), urlContainer ) );
316 rebaseLinkItemPaths( logo, urlContainer );
317 }
318
319 private List<LinkItem> mergeLinkItemLists( final List<LinkItem> childList, final List<LinkItem> parentList,
320 final URLContainer urlContainer, boolean cutParentAfterDuplicate )
321 {
322 List<LinkItem> items = new ArrayList<LinkItem>( childList.size() + parentList.size() );
323
324 for ( LinkItem item : parentList )
325 {
326 if ( !items.contains( item ) && !childList.contains( item ) )
327 {
328 final LinkItem clone = item.clone();
329
330 rebaseLinkItemPaths( clone, urlContainer );
331
332 items.add( clone );
333 }
334 else if ( cutParentAfterDuplicate )
335 {
336
337
338
339 break;
340 }
341 }
342
343 for ( LinkItem item : childList )
344 {
345 if ( !items.contains( item ) )
346 {
347 items.add( item );
348 }
349 }
350
351 return items;
352 }
353
354 private List<Logo> mergePoweredByLists( final List<Logo> childList, final List<Logo> parentList,
355 final URLContainer urlContainer )
356 {
357 List<Logo> logos = new ArrayList<Logo>( childList.size() + parentList.size() );
358
359 for ( Logo logo : parentList )
360 {
361 if ( !logos.contains( logo ) )
362 {
363 final Logo clone = logo.clone();
364
365 rebaseLogoPaths( clone, urlContainer );
366
367 logos.add( clone );
368 }
369 }
370
371 for ( Logo logo : childList )
372 {
373 if ( !logos.contains( logo ) )
374 {
375 logos.add( logo );
376 }
377 }
378
379 return logos;
380 }
381
382
383
384 private String rebaseLink( final String link, final URLContainer urlContainer )
385 {
386 if ( link == null || urlContainer.getOldPath() == null )
387 {
388 return link;
389 }
390
391 final URIPathDescriptor oldPath = new URIPathDescriptor( urlContainer.getOldPath(), link );
392
393 return oldPath.rebaseLink( urlContainer.getNewPath() ).toString();
394 }
395
396
397
398 private String relativizeLink( final String link, final String baseUri )
399 {
400 if ( link == null || baseUri == null )
401 {
402 return link;
403 }
404
405
406 try
407 {
408 final URIPathDescriptor path = new URIPathDescriptor( baseUri, link );
409
410 return path.relativizeLink().toString();
411 }
412 catch ( IllegalArgumentException e )
413 {
414 return link;
415 }
416 }
417
418
419
420
421 public final class URLContainer
422 {
423
424 private final String oldPath;
425
426 private final String newPath;
427
428
429
430
431
432
433
434 public URLContainer( final String oldPath, final String newPath )
435 {
436 this.oldPath = oldPath;
437 this.newPath = newPath;
438 }
439
440
441
442
443
444
445 public String getNewPath()
446 {
447 return this.newPath;
448 }
449
450
451
452
453
454
455 public String getOldPath()
456 {
457 return this.oldPath;
458 }
459 }
460 }