View Javadoc
1   package org.apache.maven.doxia.site.decoration.inheritance;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.Reader;
24  
25  import java.util.List;
26  
27  import junit.framework.TestCase;
28  
29  import org.apache.maven.doxia.site.decoration.Banner;
30  import org.apache.maven.doxia.site.decoration.Body;
31  import org.apache.maven.doxia.site.decoration.DecorationModel;
32  import org.apache.maven.doxia.site.decoration.LinkItem;
33  import org.apache.maven.doxia.site.decoration.Logo;
34  import org.apache.maven.doxia.site.decoration.Menu;
35  import org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Reader;
36  import org.codehaus.plexus.util.IOUtil;
37  import org.codehaus.plexus.util.ReaderFactory;
38  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39  
40  /**
41   * Test the inheritance assembler.
42   *
43   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
44   */
45  public class DecorationModelInheritanceAssemblerTest
46      extends TestCase
47  {
48      private DecorationModelInheritanceAssembler assembler = new DefaultDecorationModelInheritanceAssembler();
49  
50      private static final String NAME = "Name";
51  
52      /**
53       *
54       * @throws IOException
55       * @throws XmlPullParserException
56       */
57      public void testInheritance()
58          throws IOException, XmlPullParserException
59      {
60          DecorationModel childModel = readModel( "inheritance-child.xml" );
61          DecorationModel parentModel = readModel( "inheritance-parent.xml" );
62  
63          assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia",
64                                              "http://maven.apache.org" );
65          DecorationModel expectedModel = readModel( "inheritance-expected.xml" );
66  
67          assertEquals( "Check result", expectedModel, childModel );
68  
69          // same with scp url, DOXIASITETOOLS-47
70          childModel = readModel( "inheritance-child.xml" );
71          assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia",
72                                              "scp://people.apache.org" );
73          assertEquals( "Check scp result", expectedModel, childModel );
74  
75          assertEquals( "Modified parent!", readModel( "inheritance-parent.xml" ), parentModel );
76  
77          // late inheritance in links can't be rebased: check friendly message
78          parentModel.getBannerLeft().setHref( "${project.url}" );
79          childModel = readModel( "inheritance-child.xml" );
80          try
81          {
82              assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia",
83                                                  "scp://people.apache.org" );
84              fail( "late interpolation in link should cause IllegalArgumentException" );
85          }
86          catch ( IllegalArgumentException iae )
87          {
88              assertTrue( iae.getMessage().startsWith( "site.xml late interpolation" ) );
89          }
90      }
91  
92      /**
93       *
94       * @throws IOException
95       * @throws XmlPullParserException
96       */
97      public void testSuppressedInheritance()
98              throws IOException, XmlPullParserException
99      {
100         DecorationModel unassembledChildModel = readModel( "inheritance-child-no-inheritance.xml" );
101         DecorationModel childModel = readModel( "inheritance-child-no-inheritance.xml" );
102         DecorationModel parentModel = readModel( "inheritance-parent.xml" );
103         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia",
104                                             "http://maven.apache.org" );
105         assertEquals( "Check result", unassembledChildModel, childModel );
106 
107         // 2 levels of inheritance
108         DecorationModel childOfchildModel = new DecorationModel();
109         assembler.assembleModelInheritance( "Child of Child", childOfchildModel, childModel,
110                                             "http://maven.apache.org/doxia/child", "http://maven.apache.org/doxia" );
111         assembler.assembleModelInheritance( NAME, childOfchildModel, parentModel, "http://maven.apache.org/doxia",
112                                             "http://maven.apache.org" );
113         // check that the 3 breadcrumb items from parent.xml are not inherited
114         assertEquals( "child of child no inheritance: breadcrumbs count", 0,
115                       childOfchildModel.getBody().getBreadcrumbs().size() );
116     }
117 
118     /**
119      *
120      * @throws IOException
121      * @throws XmlPullParserException
122      */
123     public void testPathsResolvedWhenEmpty()
124         throws IOException, XmlPullParserException
125     {
126         // Test an empty model avoids NPEs
127         DecorationModel childModel = readModel( "empty.xml" );
128         DecorationModel parentModel = readModel( "empty.xml" );
129 
130         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia",
131                                             "http://maven.apache.org" );
132         DecorationModel mergedModel = readModel( "empty.xml" );
133 
134         assertEquals( "Check result", mergedModel, childModel );
135 
136         // same with scp url, DOXIASITETOOLS-47
137         childModel = readModel( "empty.xml" );
138         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia",
139                                             "scp://people.apache.org" );
140         assertEquals( "Check scp result", mergedModel, childModel );
141 
142         assertEquals( "Modified parent!", readModel( "empty.xml" ), parentModel );
143     }
144 
145     /**
146      *
147      * @throws IOException
148      * @throws XmlPullParserException
149      */
150     public void testPathsNotResolvedForExternalUrls()
151         throws IOException, XmlPullParserException
152     {
153         DecorationModel parentModel = readModel( "external-urls.xml" );
154         DecorationModel childModel = readModel( "empty.xml" );
155 
156         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia",
157                                             "http://maven.apache.org" );
158         assertPathsNotResolvedForExternalUrls( childModel );
159 
160         // same with scp url, DOXIASITETOOLS-47
161         childModel = readModel( "empty.xml" );
162         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia",
163                                             "scp://people.apache.org" );
164         assertPathsNotResolvedForExternalUrls( childModel );
165 
166         assertEquals( "Modified parent!", readModel( "external-urls.xml" ), parentModel );
167     }
168 
169     private static void assertPathsNotResolvedForExternalUrls( final DecorationModel childModel )
170     {
171         assertEquals( "check left banner href", "http://jakarta.apache.org/", childModel.getBannerLeft().getHref() );
172         assertEquals( "check left banner image", "http://jakarta.apache.org/images/jakarta-logo.gif",
173                       childModel.getBannerLeft().getSrc() );
174 
175         assertEquals( "check right banner href", "http://jakarta.apache.org/commons/sandbox",
176                       childModel.getBannerRight().getHref() );
177         assertEquals( "check right banner image", "http://jakarta.apache.org/commons/images/logo.png",
178                       childModel.getBannerRight().getSrc() );
179 
180         Logo poweredBy = childModel.getPoweredBy().get( 0 );
181         assertEquals( "check powered by logo href", "http://tomcat.apache.org/", poweredBy.getHref() );
182         assertEquals( "check powered by logo image", "http://tomcat.apache.org/logo.gif", poweredBy.getImg() );
183 
184         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
185         assertEquals( "check breadcrumb href", "http://www.apache.org/", breadcrumb.getHref() );
186 
187         LinkItem link = childModel.getBody().getLinks().get( 0 );
188         assertEquals( "check link href", "http://www.bouncycastle.org", link.getHref() );
189 
190         Menu menu = childModel.getBody().getMenus().get( 0 );
191         LinkItem menuItem = menu.getItems().get( 0 );
192         assertEquals( "check menu item href", "http://www.apache.org/special/", menuItem.getHref() );
193     }
194 
195     /**
196      *
197      * @throws IOException
198      * @throws XmlPullParserException
199      */
200     public void testPathsResolvedForRelativeUrls()
201         throws IOException, XmlPullParserException
202     {
203         DecorationModel parentModel = readModel( "relative-urls.xml" );
204         DecorationModel childModel = readModel( "empty.xml" );
205 
206         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia/",
207                                             "http://maven.apache.org" );
208         assertPathsResolvedForRelativeUrls( childModel );
209 
210         // same with scp url, DOXIASITETOOLS-47
211         childModel = readModel( "empty.xml" );
212         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia",
213                                             "scp://people.apache.org" );
214         assertPathsResolvedForRelativeUrls( childModel );
215 
216         assertEquals( "Modified parent!", readModel( "relative-urls.xml" ), parentModel );
217     }
218 
219     private static void assertPathsResolvedForRelativeUrls( final DecorationModel childModel )
220     {
221         assertEquals( "check left banner href", "../banner/left", childModel.getBannerLeft().getHref() );
222         assertEquals( "check left banner image", "../images/jakarta-logo.gif", childModel.getBannerLeft().getSrc() );
223 
224         assertEquals( "check right banner href", "../banner/right/", childModel.getBannerRight().getHref() );
225         assertEquals( "check right banner image", "../commons/images/logo.png", childModel.getBannerRight().getSrc() );
226 
227         Logo poweredBy = childModel.getPoweredBy().get( 0 );
228         assertEquals( "check powered by logo href", "../tomcat", poweredBy.getHref() );
229         assertEquals( "check powered by logo image", "../tomcat/logo.gif", poweredBy.getImg() );
230 
231         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
232         assertEquals( "check breadcrumb href", "../apache", breadcrumb.getHref() );
233 
234         LinkItem link = childModel.getBody().getLinks().get( 0 );
235         assertEquals( "check link href", "../bouncycastle/", link.getHref() );
236 
237         Menu menu = childModel.getBody().getMenus().get( 0 );
238         LinkItem menuItem = menu.getItems().get( 0 );
239         assertEquals( "check menu item href", "../special/", menuItem.getHref() );
240     }
241 
242     /**
243      *
244      * @throws IOException
245      * @throws XmlPullParserException
246      */
247     public void testPathsResolvedForSubsiteUrls()
248         throws IOException, XmlPullParserException
249     {
250         DecorationModel parentModel = readModel( "subsite-urls.xml" );
251         DecorationModel childModel = readModel( "empty.xml" );
252 
253         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia/",
254                                             "http://maven.apache.org" );
255         assembler.resolvePaths( childModel, "http://maven.apache.org/doxia" );
256 
257         assertPathsResolvedForSubsiteUrls( childModel );
258 
259         // same with scp url, DOXIASITETOOLS-47
260         childModel = readModel( "empty.xml" );
261         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia",
262                                             "scp://people.apache.org" );
263         assembler.resolvePaths( childModel, "http://maven.apache.org/doxia" );
264         assertPathsResolvedForSubsiteUrls( childModel );
265 
266         assertEquals( "Modified parent!", readModel( "subsite-urls.xml" ), parentModel );
267     }
268 
269     private static void assertPathsResolvedForSubsiteUrls( final DecorationModel childModel )
270     {
271         assertEquals( "check left banner href", "../banner/left", childModel.getBannerLeft().getHref() );
272         assertEquals( "check left banner image", "../images/jakarta-logo.gif", childModel.getBannerLeft().getSrc() );
273 
274         assertEquals( "check right banner href", "../banner/right/", childModel.getBannerRight().getHref() );
275         assertEquals( "check right banner image", "../commons/images/logo.png", childModel.getBannerRight().getSrc() );
276 
277         Logo poweredBy = childModel.getPoweredBy().get( 0 );
278         assertEquals( "check powered by logo href", "../tomcat", poweredBy.getHref() );
279         assertEquals( "check powered by logo image", "../tomcat/logo.gif", poweredBy.getImg() );
280 
281         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
282         assertEquals( "check breadcrumb href", "../apache", breadcrumb.getHref() );
283 
284         LinkItem link = childModel.getBody().getLinks().get( 0 );
285         assertEquals( "check link href", "../bouncycastle/", link.getHref() );
286 
287         Menu menu = childModel.getBody().getMenus().get( 0 );
288         LinkItem menuItem = menu.getItems().get( 0 );
289         assertEquals( "check menu item href", "../special/", menuItem.getHref() );
290     }
291 
292     /**
293      *
294      * @throws IOException
295      * @throws XmlPullParserException
296      */
297     public void testPathsResolvedForRelativeUrlsDepthOfTwo()
298         throws IOException, XmlPullParserException
299     {
300         DecorationModel parentModel = readModel( "relative-urls.xml" );
301         DecorationModel childModel = readModel( "empty.xml" );
302 
303         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia/core",
304                                             "http://maven.apache.org" );
305         assertPathsResolvedForRelativeUrlsDepthOfTwo( childModel );
306 
307         // same with scp url, DOXIASITETOOLS-47
308         childModel = readModel( "empty.xml" );
309         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/doxia/core",
310                                             "scp://people.apache.org" );
311         assertPathsResolvedForRelativeUrlsDepthOfTwo( childModel );
312 
313         assertEquals( "Modified parent!", readModel( "relative-urls.xml" ), parentModel );
314     }
315 
316     private static void assertPathsResolvedForRelativeUrlsDepthOfTwo( final DecorationModel childModel )
317     {
318         assertEquals( "check left banner href", "../../banner/left", childModel.getBannerLeft().getHref() );
319         assertEquals( "check left banner image", "../../images/jakarta-logo.gif", childModel.getBannerLeft().getSrc() );
320 
321         assertEquals( "check right banner href", "../../banner/right/", childModel.getBannerRight().getHref() );
322         assertEquals( "check right banner image", "../../commons/images/logo.png",
323                       childModel.getBannerRight().getSrc() );
324 
325         Logo poweredBy = childModel.getPoweredBy().get( 0 );
326         assertEquals( "check powered by logo href", "../../tomcat", poweredBy.getHref() );
327         assertEquals( "check powered by logo image", "../../tomcat/logo.gif", poweredBy.getImg() );
328 
329         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
330         assertEquals( "check breadcrumb href", "../../apache", breadcrumb.getHref() );
331 
332         LinkItem link = childModel.getBody().getLinks().get( 0 );
333         assertEquals( "check link href", "../../bouncycastle/", link.getHref() );
334 
335         Menu menu = childModel.getBody().getMenus().get( 0 );
336         LinkItem menuItem = menu.getItems().get( 0 );
337         assertEquals( "check menu item href", "../../special/", menuItem.getHref() );
338     }
339 
340     /**
341      *
342      * @throws IOException
343      * @throws XmlPullParserException
344      */
345     public void testPathsResolvedForReverseRelativeUrls()
346         throws IOException, XmlPullParserException
347     {
348         DecorationModel parentModel = readModel( "relative-urls.xml" );
349         DecorationModel childModel = readModel( "empty.xml" );
350 
351         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/",
352                                             "http://maven.apache.org/doxia/" );
353         assertPathsResolvedForReverseRelativeUrls( childModel );
354 
355         // same with scp url, DOXIASITETOOLS-47
356         childModel = readModel( "empty.xml" );
357         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/",
358                                             "scp://people.apache.org/doxia/" );
359         assertPathsResolvedForReverseRelativeUrls( childModel );
360 
361         assertEquals( "Modified parent!", readModel( "relative-urls.xml" ), parentModel );
362     }
363 
364     private static void assertPathsResolvedForReverseRelativeUrls( final DecorationModel childModel )
365     {
366         assertEquals( "check left banner href", "doxia/banner/left", childModel.getBannerLeft().getHref() );
367         assertEquals( "check left banner image", "doxia/images/jakarta-logo.gif", childModel.getBannerLeft().getSrc() );
368 
369         assertEquals( "check right banner href", "doxia/banner/right/", childModel.getBannerRight().getHref() );
370         assertEquals( "check right banner image", "doxia/commons/images/logo.png",
371                       childModel.getBannerRight().getSrc() );
372 
373         Logo poweredBy = childModel.getPoweredBy().get( 0 );
374         assertEquals( "check powered by logo href", "doxia/tomcat", poweredBy.getHref() );
375         assertEquals( "check powered by logo image", "doxia/tomcat/logo.gif", poweredBy.getImg() );
376 
377         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
378         assertEquals( "check breadcrumb href", "doxia/apache", breadcrumb.getHref() );
379 
380         LinkItem link = childModel.getBody().getLinks().get( 0 );
381         assertEquals( "check link href", "doxia/bouncycastle/", link.getHref() );
382 
383         Menu menu = childModel.getBody().getMenus().get( 0 );
384         LinkItem menuItem = menu.getItems().get( 0 );
385         assertEquals( "check menu item href", "doxia/special/", menuItem.getHref() );
386     }
387 
388     /**
389      *
390      * @throws IOException
391      * @throws XmlPullParserException
392      */
393     public void testPathsResolvedForReverseRelativeUrlsDepthOfTwo()
394         throws IOException, XmlPullParserException
395     {
396         DecorationModel parentModel = readModel( "relative-urls.xml" );
397         DecorationModel childModel = readModel( "empty.xml" );
398 
399         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/",
400                                             "http://maven.apache.org/doxia/core/" );
401         assertPathsResolvedForReverseRelativeUrlsDepthOfTwo( childModel );
402 
403         // same with scp url, DOXIASITETOOLS-47
404         childModel = readModel( "empty.xml" );
405         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/",
406                                             "scp://people.apache.org/doxia/core/" );
407         assertPathsResolvedForReverseRelativeUrlsDepthOfTwo( childModel );
408 
409         assertEquals( "Modified parent!", readModel( "relative-urls.xml" ), parentModel );
410     }
411 
412     private static void assertPathsResolvedForReverseRelativeUrlsDepthOfTwo( final DecorationModel childModel )
413     {
414         assertEquals( "check left banner href", "doxia/core/banner/left", childModel.getBannerLeft().getHref() );
415         assertEquals( "check left banner image", "doxia/core/images/jakarta-logo.gif",
416                       childModel.getBannerLeft().getSrc() );
417 
418         assertEquals( "check right banner href", "doxia/core/banner/right/", childModel.getBannerRight().getHref() );
419         assertEquals( "check right banner image", "doxia/core/commons/images/logo.png",
420                       childModel.getBannerRight().getSrc() );
421 
422         Logo poweredBy = childModel.getPoweredBy().get( 0 );
423         assertEquals( "check powered by logo href", "doxia/core/tomcat", poweredBy.getHref() );
424         assertEquals( "check powered by logo image", "doxia/core/tomcat/logo.gif", poweredBy.getImg() );
425 
426         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
427         assertEquals( "check breadcrumb href", "doxia/core/apache", breadcrumb.getHref() );
428 
429         LinkItem link = childModel.getBody().getLinks().get( 0 );
430         assertEquals( "check link href", "doxia/core/bouncycastle/", link.getHref() );
431 
432         Menu menu = childModel.getBody().getMenus().get( 0 );
433         LinkItem menuItem = menu.getItems().get( 0 );
434         assertEquals( "check menu item href", "doxia/core/special/", menuItem.getHref() );
435     }
436 
437     /**
438      *
439      * @throws IOException
440      * @throws XmlPullParserException
441      */
442     public void testPathsResolvedForUnrelatedRelativeUrls()
443         throws IOException, XmlPullParserException
444     {
445         DecorationModel parentModel = readModel( "relative-urls.xml" );
446         DecorationModel childModel = readModel( "empty.xml" );
447 
448         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org",
449                                             "http://jakarta.apache.org" );
450         assertPathsResolvedForUnrelatedRelativeUrls( childModel );
451 
452         // same with scp url, DOXIASITETOOLS-47
453         childModel = readModel( "empty.xml" );
454         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://people.apache.org/",
455                                             "http://jakarta.apache.org" );
456         assertPathsResolvedForUnrelatedRelativeUrls( childModel );
457 
458         assertEquals( "Modified parent!", readModel( "relative-urls.xml" ), parentModel );
459     }
460 
461     private static void assertPathsResolvedForUnrelatedRelativeUrls( final DecorationModel childModel )
462     {
463         assertEquals( "check left banner href", "http://jakarta.apache.org/banner/left",
464                       childModel.getBannerLeft().getHref() );
465         assertEquals( "check left banner image", "http://jakarta.apache.org/images/jakarta-logo.gif",
466                       childModel.getBannerLeft().getSrc() );
467 
468         assertEquals( "check right banner href", "http://jakarta.apache.org/banner/right/",
469                       childModel.getBannerRight().getHref() );
470         assertEquals( "check right banner image", "http://jakarta.apache.org/commons/images/logo.png",
471                       childModel.getBannerRight().getSrc() );
472 
473         Logo poweredBy = childModel.getPoweredBy().get( 0 );
474         assertEquals( "check powered by logo href", "http://jakarta.apache.org/tomcat", poweredBy.getHref() );
475         assertEquals( "check powered by logo image", "http://jakarta.apache.org/tomcat/logo.gif", poweredBy.getImg() );
476 
477         LinkItem breadcrumb = childModel.getBody().getBreadcrumbs().get( 0 );
478         assertEquals( "check breadcrumb href", "http://jakarta.apache.org/apache", breadcrumb.getHref() );
479 
480         LinkItem link = childModel.getBody().getLinks().get( 0 );
481         assertEquals( "check link href", "http://jakarta.apache.org/bouncycastle/", link.getHref() );
482 
483         Menu menu = childModel.getBody().getMenus().get( 0 );
484         LinkItem menuItem = menu.getItems().get( 0 );
485         assertEquals( "check menu item href", "http://jakarta.apache.org/special/", menuItem.getHref() );
486     }
487 
488     /**
489      *
490      * @throws IOException
491      * @throws XmlPullParserException
492      */
493     public void testNullParent()
494         throws IOException, XmlPullParserException
495     {
496         DecorationModel childModel = readModel( "empty.xml" );
497 
498         assembler.assembleModelInheritance( NAME, childModel, null, "http://maven.apache.org/doxia",
499                                             "http://maven.apache.org" );
500         DecorationModel mergedModel = readModel( "empty.xml" );
501 
502         assertEquals( "Check result", mergedModel, childModel );
503 
504         // same with scp url, DOXIASITETOOLS-47
505         childModel = readModel( "empty.xml" );
506         assembler.assembleModelInheritance( NAME, childModel, null, "scp://people.apache.org/doxia",
507                                             "scp://people.apache.org" );
508         assertEquals( "Check scp result", mergedModel, childModel );
509     }
510 
511     /**
512      *
513      * @throws IOException
514      * @throws XmlPullParserException
515      */
516     public void testFullyPopulatedChild()
517         throws IOException, XmlPullParserException
518     {
519         DecorationModel childModel = readModel( "fully-populated-child.xml" );
520         DecorationModel parentModel = readModel( "fully-populated-child.xml" );
521 
522         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://foo.apache.org/doxia",
523                                             "http://foo.apache.org" );
524         DecorationModel mergedModel = readModel( "fully-populated-child.xml" );
525 
526         assertEquals( "Check result", mergedModel, childModel );
527 
528         // same with scp url, DOXIASITETOOLS-47
529         childModel = readModel( "fully-populated-child.xml" );
530         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://foo.apache.org/doxia",
531                                             "scp://foo.apache.org" );
532         assertEquals( "Check scp result", mergedModel, childModel );
533 
534         assertEquals( "Modified parent!", readModel( "fully-populated-child.xml" ), parentModel );
535     }
536 
537     /**
538      *
539      * @throws IOException
540      * @throws XmlPullParserException
541      */
542     public void testFullyPopulatedParentAndEmptyChild()
543         throws IOException, XmlPullParserException
544     {
545         DecorationModel childModel = readModel( "empty.xml" );
546         DecorationModel parentModel = readModel( "fully-populated-child.xml" );
547 
548         assembler.assembleModelInheritance( NAME, childModel, parentModel, "http://maven.apache.org/doxia",
549                                             "http://maven.apache.org" );
550 
551         DecorationModel unresolvedModel = readModel( "fully-populated-unresolved.xml" );
552         assertEquals( "Check result", unresolvedModel, childModel );
553 
554         assembler.resolvePaths( childModel, "http://maven.apache.org/doxia" );
555         DecorationModel mergedModel = readModel( "fully-populated-merged.xml" );
556 
557         assertEquals( "Check result", mergedModel, childModel );
558 
559         // same with scp url, DOXIASITETOOLS-47
560         childModel = readModel( "empty.xml" );
561         assembler.assembleModelInheritance( NAME, childModel, parentModel, "scp://maven.apache.org/doxia",
562                                             "scp://maven.apache.org" );
563         assembler.resolvePaths( childModel, "http://maven.apache.org/doxia" );
564         assertEquals( "Check scp result", mergedModel, childModel );
565 
566         assertEquals( "Modified parent!", readModel( "fully-populated-child.xml" ), parentModel );
567     }
568 
569     /**
570      *
571      * @throws IOException
572      * @throws XmlPullParserException
573      */
574     public void testResolvingAllExternalUrls()
575         throws IOException, XmlPullParserException
576     {
577         DecorationModel model = readModel( "external-urls.xml" );
578 
579         assembler.resolvePaths( model, "http://foo.com/" );
580         DecorationModel mergedModel = readModel( "external-urls.xml" );
581 
582         assertEquals( "Check result", mergedModel, model );
583     }
584 
585     /**
586      *
587      * @throws IOException
588      * @throws XmlPullParserException
589      */
590     public void testResolvingAllRelativeUrls()
591         throws IOException, XmlPullParserException
592     {
593         DecorationModel model = readModel( "relative-urls.xml" );
594 
595         assembler.resolvePaths( model, "http://foo.com/" );
596 
597         DecorationModel resolvedModel = readModel( "relative-urls-resolved.xml" );
598 
599         assertEquals( "Check result", resolvedModel, model );
600     }
601 
602     /**
603      *
604      * @throws IOException
605      * @throws XmlPullParserException
606      */
607     public void testResolvingAllSiteUrls()
608         throws IOException, XmlPullParserException
609     {
610         DecorationModel model = readModel( "subsite-urls.xml" );
611 
612         assembler.resolvePaths( model, "http://maven.apache.org/" );
613 
614         DecorationModel resolvedModel = readModel( "relative-urls-resolved.xml" );
615         assertEquals( "Check result", resolvedModel, model );
616     }
617 
618 /* [MSITE-62] This is to test the ../ relative paths, which I am inclined not to use
619     public void testResolvingAllSiteChildUrls()
620         throws IOException, XmlPullParserException
621     {
622         DecorationModel model = readModel( "subsite-urls.xml" );
623 
624         assembler.resolvePaths( model, "http://maven.apache.org/foo" );
625 
626         DecorationModel resolvedModel = readModel( "subsite-relative-urls-resolved.xml" );
627         assertEquals( "Check result", resolvedModel, model );
628     }
629 
630     public void testResolvingAllSiteChildUrlsMultipleLevels()
631         throws IOException, XmlPullParserException
632     {
633         DecorationModel model = readModel( "subsite-urls.xml" );
634 
635         assembler.resolvePaths( model, "http://maven.apache.org/banner/right" );
636 
637         DecorationModel resolvedModel = readModel( "subsite-relative-urls-multiple-resolved.xml" );
638         assertEquals( "Check result", resolvedModel, model );
639     }
640 
641     public void testResolvingAllSiteChildFilesystemUrls()
642         throws IOException, XmlPullParserException
643     {
644         DecorationModel model = readModel( "subsite-urls-file.xml" );
645 
646         assembler.resolvePaths( model, "file://localhost/www/maven.apache.org/foo" );
647 
648         DecorationModel resolvedModel = readModel( "subsite-relative-urls-resolved.xml" );
649         assertEquals( "Check result", resolvedModel, model );
650     }
651 
652 */
653 
654     /**
655      *
656      * @throws IOException
657      * @throws XmlPullParserException
658      */
659     public void testResolvingEmptyDescriptor()
660         throws IOException, XmlPullParserException
661     {
662         DecorationModel model = readModel( "empty.xml" );
663         assembler.resolvePaths( model, "http://maven.apache.org" );
664         DecorationModel mergedModel = readModel( "empty.xml" );
665 
666         assertEquals( "Check result", mergedModel, model );
667     }
668 
669     /**
670      *
671      */
672     public void testDuplicateParentElements()
673     {
674         DecorationModel model = new DecorationModel();
675         model.setBody( new Body() );
676         model.getBody().addLink( createLinkItem( "Foo", "http://foo.apache.org" ) );
677         model.getBody().addLink( createLinkItem( "Foo", "http://foo.apache.org" ) );
678 
679         model.addPoweredBy( createLogo( "Foo", "http://foo.apache.org", "http://foo.apache.org/foo.jpg" ) );
680         model.addPoweredBy( createLogo( "Foo", "http://foo.apache.org", "http://foo.apache.org/foo.jpg" ) );
681 
682         DecorationModel child = new DecorationModel();
683         assembler.assembleModelInheritance( NAME, child, model, "http://maven.apache.org/doxia",
684                                             "http://maven.apache.org" );
685 
686         assertEquals( "Check size", 1, child.getBody().getLinks().size() );
687         assertEquals( "Check item", createLinkItem( "Foo", "http://foo.apache.org" ),
688                       child.getBody().getLinks().get( 0 ) );
689 
690         assertEquals( "Check size", 1, child.getPoweredBy().size() );
691         assertEquals( "Check item", createLogo( "Foo", "http://foo.apache.org", "http://foo.apache.org/foo.jpg" ),
692                       child.getPoweredBy().get( 0 ) );
693     }
694 
695     /**
696      *
697      */
698     public void testDuplicateChildElements()
699     {
700         DecorationModel model = new DecorationModel();
701         model.setBody( new Body() );
702         model.getBody().addLink( createLinkItem( "Foo", "http://foo.apache.org" ) );
703         model.getBody().addLink( createLinkItem( "Foo", "http://foo.apache.org" ) );
704 
705         model.addPoweredBy( createLogo( "Foo", "http://foo.apache.org", "http://foo.apache.org/foo.jpg" ) );
706         model.addPoweredBy( createLogo( "Foo", "http://foo.apache.org", "http://foo.apache.org/foo.jpg" ) );
707 
708         DecorationModel parent = new DecorationModel();
709         assembler.assembleModelInheritance( NAME, model, parent, "http://maven.apache.org/doxia",
710                                             "http://maven.apache.org" );
711 
712         assertEquals( "Check size", 1, model.getBody().getLinks().size() );
713         assertEquals( "Check item", createLinkItem( "Foo", "http://foo.apache.org" ),
714                       model.getBody().getLinks().get( 0 ) );
715 
716         assertEquals( "Check size", 1, model.getPoweredBy().size() );
717         assertEquals( "Check item", createLogo( "Foo", "http://foo.apache.org", "http://foo.apache.org/foo.jpg" ),
718                       model.getPoweredBy().get( 0 ) );
719 
720         assertEquals( "Modified parent!", new DecorationModel(), parent );
721     }
722 
723     /**
724      *
725      */
726     public void testBadHref()
727     {
728         final DecorationModel model = new DecorationModel();
729         model.setBody( new Body() );
730         model.getBody().addBreadcrumb( createLinkItem( "Foo", "http://foo.apache.org/${property}" ) );
731         assembler.resolvePaths( model, "http://foo.apache.org" );
732         assertEquals( "Check size", 1, model.getBody().getBreadcrumbs().size() );
733         assertEquals( "Check item", createLinkItem( "Foo", "http://foo.apache.org/${property}" ),
734             model.getBody().getBreadcrumbs().get( 0 ) );
735     }
736 
737     /**
738      *
739      */
740     public void testBreadcrumbWithoutHref()
741     {
742         DecorationModel model = new DecorationModel();
743         model.setBody( new Body() );
744         model.getBody().addBreadcrumb( createLinkItem( "Foo", null ) );
745         assembler.resolvePaths( model, "http://foo.apache.org" );
746         assertEquals( "Check size", 1, model.getBody().getBreadcrumbs().size() );
747         assertEquals( "Check item", createLinkItem( "Foo", null ), model.getBody().getBreadcrumbs().get( 0 ) );
748     }
749 
750     /**
751      *
752      */
753     public void testBreadcrumbs()
754     {
755         String parentHref = "http://parent.com/index.html";
756 
757         final DecorationModel parent = new DecorationModel();
758         parent.setBody( new Body() );
759         parent.getBody().addBreadcrumb( createLinkItem( "Parent", parentHref ) );
760 
761         DecorationModel child = new DecorationModel();
762         assembler.assembleModelInheritance( "childName", child, parent,
763                 "http://parent.com/child", "http://parent.com" );
764         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "childName", parentHref );
765 
766 
767         // same with trailing slash
768         child = new DecorationModel();
769         assembler.assembleModelInheritance( "childName", child, parent,
770                 "http://parent.com/child/", "http://parent.com/" );
771         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "childName", parentHref );
772 
773         // now mixed
774         child = new DecorationModel();
775         assembler.assembleModelInheritance( "childName", child, parent,
776                 "http://parent.com/child/", "http://parent.com" );
777         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "childName", parentHref );
778 
779         // and other way round
780         child = new DecorationModel();
781         assembler.assembleModelInheritance( "childName", child, parent,
782                 "http://parent.com/child", "http://parent.com/" );
783         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "childName", parentHref );
784 
785 
786         // now with child breadcrumb
787         child = new DecorationModel();
788         child.setBody( new Body() );
789         child.getBody().addBreadcrumb( createLinkItem( "Child", "index.html" ) );
790         assembler.assembleModelInheritance( "childName", child, parent,
791                 "http://parent.com/child/", "http://parent.com/" );
792         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "Child", parentHref );
793 
794 
795         // now with file url
796         parentHref = "file://parent.com/index.html";
797         ( parent.getBody().getBreadcrumbs().get( 0 ) ).setHref( parentHref );
798         child = new DecorationModel();
799         assembler.assembleModelInheritance( "childName", child, parent,
800                 "file://parent.com/child/", "file://parent.com/" );
801         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "childName", parentHref );
802 
803 
804         // now with scp url
805         parentHref = "scp://parent.com/index.html";
806         ( parent.getBody().getBreadcrumbs().get( 0 ) ).setHref( parentHref );
807         child = new DecorationModel();
808         assembler.assembleModelInheritance( "childName", child, parent,
809                 "scp://parent.com/child/", "scp://parent.com/" );
810         assertBreadcrumbsCorrect( child.getBody().getBreadcrumbs(), "childName", parentHref );
811     }
812 
813     private static void assertBreadcrumbsCorrect( final List<LinkItem> breadcrumbs, final String childName,
814             final String parentHref )
815     {
816         assertEquals( "Check size", 2, breadcrumbs.size() );
817         assertEquals( "Check parent item", createLinkItem( "Parent", parentHref ), breadcrumbs.get( 0 ) );
818         assertEquals( "Check child item", createLinkItem( childName, "index.html" ), breadcrumbs.get( 1 ) );
819     }
820 
821     /**
822      * https://issues.apache.org/jira/browse/DOXIASITETOOLS-62
823      */
824     public void testBreadcrumbCutParentAfterDuplicate()
825     {
826         DecorationModel child = new DecorationModel(); // B > E
827         child.setBody( new Body() );
828         child.getBody().addBreadcrumb( createLinkItem( "B", null ) );
829         child.getBody().addBreadcrumb( createLinkItem( "E", null ) );
830 
831         DecorationModel parent = new DecorationModel(); // A > B > C > D
832         parent.setBody( new Body() );
833         parent.getBody().addBreadcrumb( createLinkItem( "A", null ) );
834         parent.getBody().addBreadcrumb( createLinkItem( "B", null ) );
835         parent.getBody().addBreadcrumb( createLinkItem( "C", null ) );
836         parent.getBody().addBreadcrumb( createLinkItem( "D", null ) );
837 
838         assembler.assembleModelInheritance( NAME, child, parent, "http://maven.apache.org/doxia",
839                                             "http://maven.apache.org" );
840 
841         final List<LinkItem> breadcrumbs = child.getBody().getBreadcrumbs(); // expected: A > B > E
842         assertEquals( "Check size", 3, breadcrumbs.size() );
843         assertEquals( "Check item", createLinkItem( "A", null ), breadcrumbs.get( 0 ) );
844         assertEquals( "Check item", createLinkItem( "B", null ), breadcrumbs.get( 1 ) );
845         assertEquals( "Check item", createLinkItem( "E", null ), breadcrumbs.get( 2 ) );
846     }
847 
848     /**
849      *
850      */
851     public void testBannerWithoutHref()
852     {
853         DecorationModel model = new DecorationModel();
854         model.setBody( new Body() );
855 
856         Banner banner = createBanner( "Left", null, "/images/src.gif", "alt" );
857 
858         model.setBannerLeft( banner );
859 
860         assembler.resolvePaths( model, "http://foo.apache.org" );
861 
862         assertEquals( "Check banner", createBanner( "Left", null, "images/src.gif", "alt" ), model.getBannerLeft() );
863     }
864 
865     /**
866      *
867      */
868     public void testLogoWithoutImage()
869     {
870         // This should actually be validated in the model, it doesn't really make sense
871         DecorationModel model = new DecorationModel();
872         model.setBody( new Body() );
873         model.addPoweredBy( createLogo( "Foo", "http://foo.apache.org", null ) );
874         assembler.resolvePaths( model, "http://foo.apache.org" );
875         assertEquals( "Check size", 1, model.getPoweredBy().size() );
876         assertEquals( "Check item", createLogo( "Foo", "./", null ), model.getPoweredBy().get( 0 ) );
877     }
878 
879     private static Banner createBanner( String name, String href, String src, String alt )
880     {
881         Banner banner = new Banner();
882         banner.setName( name );
883         banner.setHref( href );
884         banner.setSrc( src );
885         banner.setAlt( alt );
886         return banner;
887     }
888 
889     private Logo createLogo( String name, String href, String img )
890     {
891         Logo logo = new Logo();
892         logo.setHref( href );
893         logo.setImg( img );
894         logo.setName( name );
895         return logo;
896     }
897 
898     private static LinkItem createLinkItem( String name, String href )
899     {
900         LinkItem item = new LinkItem();
901         item.setName( name );
902         item.setHref( href );
903         return item;
904     }
905 
906     private DecorationModel readModel( String name )
907         throws IOException, XmlPullParserException
908     {
909         Reader reader = null;
910         try
911         {
912             reader = ReaderFactory.newXmlReader( getClass().getResourceAsStream( "/" + name ) );
913             return new DecorationXpp3Reader().read( reader );
914         }
915         finally
916         {
917             IOUtil.close( reader );
918         }
919     }
920 }