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