1   /*
2    * Copyright 2000-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.jetspeed.services.portaltoolkit;
17  
18  import java.io.BufferedReader;
19  import java.io.BufferedWriter;
20  import java.io.File;
21  import java.io.FileReader;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  import java.util.Enumeration;
25  import java.util.HashMap;
26  import java.util.Iterator;
27  import java.util.List;
28  
29  import junit.framework.Test;
30  import junit.framework.TestSuite;
31  
32  import org.apache.commons.lang.exception.NestableException;
33  import org.apache.jetspeed.om.profile.IdentityElement;
34  import org.apache.jetspeed.om.profile.PSMLDocument;
35  import org.apache.jetspeed.om.profile.Portlets;
36  import org.apache.jetspeed.om.profile.Skin;
37  import org.apache.jetspeed.om.profile.psml.PsmlEntry;
38  import org.apache.jetspeed.om.profile.psml.PsmlSkin;
39  import org.apache.jetspeed.portal.Portlet;
40  import org.apache.jetspeed.portal.PortletSet;
41  import org.apache.jetspeed.services.PortalToolkit;
42  import org.apache.jetspeed.test.HeadlessBaseTest;
43  import org.apache.turbine.services.TurbineServices;
44  import org.apache.turbine.services.resources.ResourceService;
45  
46  /***
47   * @author <a href="mailto:sweaver@rippe.com">Scott Weaver</a>
48   *	Tests different use cases of what happens when skins are requested
49   *  /applied. 
50   *  
51   */
52  public class TestSkinAggregation extends HeadlessBaseTest
53  {
54  
55      public static String SKIN_TEST_PATH = "skin.test";
56      public static String SKIN_TEST2_PATH = "skin.test2";
57      public static String SKIN_TEST3_PATH = "skin.test3";
58      public static String SKIN_TEST4_PATH = "skin.test4";
59  
60      private File prof1;
61      private File prof2;
62      private File prof3;
63      private File prof4;
64  
65  
66      private String defaultSkin;
67  
68      public TestSkinAggregation(String name)
69      {
70          super(name);
71      }
72  
73      /***
74       * 1) no skin ref in PSML
75       * RESULT: uses default skin
76       * 
77       * This tests to see that, when no skin is defined, the default skin is
78       * used.
79       */
80      public void testCase1()
81      {
82          printDivider();
83          print("Description: No skin set in PSML ");
84          print("RESULT: All portlets use the system default skin.");
85          print("Checking test case 1...");
86          File file = createTestProfile(prof1);
87          PSMLDocument doc = getDocumentFromPath(file.getPath());
88          Portlets portlets = doc.getPortlets();
89          print("Portlets loaded as: " + portlets);
90  
91          // checkSkinPresence(portlets, null);
92  
93          print("Using the PortalToolkit.  All Portlets and PsmlEntries (individual portlets) ");
94          print("should now be using the system default skin, " + this.defaultSkin);
95  
96          PortletSet pSet = PortalToolkit.getSet(portlets);
97          assertNotNull(pSet);
98  
99          // Checking if we are at the root
100         isRoot(pSet);
101 
102         checkPortletSkinValues(pSet, new HashMap(), doc);
103 
104         print("Saving test document...");
105         saveDocument(doc);
106         printOk();
107         print("Re-run check to make sure that the default setting did not get written...");
108         PSMLDocument doc2 = getDocumentFromPath(file.getPath());
109         Portlets portlets2 = doc.getPortlets();
110         PortletSet pSet2 = PortalToolkit.getSet(portlets2);
111 
112         checkPortletSkinValues(pSet2, new HashMap(), doc2);
113 
114         printDivider();
115     }
116 
117     /***
118      * Checks if the file path of skin.test exists and is accessable
119      */
120     public void testLoadSkinPath()
121     {
122 
123         printDivider();
124         print("Checking skin test profile...");
125         assertTrue(prof1.exists());
126         assertTrue(prof2.exists());
127         print("Found skin test profile at: " + prof1.getPath());
128         printDivider();
129     }
130 
131     /***
132      * 1) no skin ref in PSML
133      * RESULT: uses default skin
134      * 
135      * This tests to see that, when no skin is defined, the default skin is
136      * used.
137      */
138     public void testCase2()
139     {
140         printDivider();
141         print("Description: Skin set at root level, skin set in any children.");
142         print("RESULT: All portlets use the root level skin");
143         print("Checking test case 2...");
144         File file = createTestProfile(prof2);
145         PSMLDocument doc = getDocumentFromPath(file.getPath());
146         Portlets portlets = doc.getPortlets();
147         print("Portlets loaded as: " + portlets);
148 
149         print("Save and re-open document as if it were being loaded for the first time...");
150         saveDocument(doc);
151         // re-load everything...
152         doc = null;
153         doc = getDocumentFromPath(file.getPath());
154         portlets = doc.getPortlets();
155 
156         print("Using the PortalToolkit.  All Portlets and PsmlEntries (individual portlets) ");
157 
158         PortletSet pSet = PortalToolkit.getSet(portlets);
159         assertNotNull(pSet);
160 
161         // Checking if we are at the root
162         isRoot(pSet);
163         HashMap settingsMap = new HashMap();
164         settingsMap.put(portlets.getId(), new MatchSettings(false, false, "grey", true));
165         settingsMap.put("02", new MatchSettings(false, true, null, false));
166         settingsMap.put("03", new MatchSettings(false, true, null, false));
167         settingsMap.put("04", new MatchSettings(false, true, null, false));
168         settingsMap.put("05", new MatchSettings(false, true, null, false));
169         settingsMap.put("06", new MatchSettings(false, true, null, false));
170         settingsMap.put("07", new MatchSettings(false, true, null, false));
171         settingsMap.put("08", new MatchSettings(false, true, null, false));
172 
173         checkPortletSkinValues(pSet, settingsMap, doc);
174         printOk();
175 
176         printDivider();
177     }
178     
179     
180     /***
181      * Case 3
182       */
183     public void testCase3()
184     {
185         printDivider();
186         print("Description: Skin set at top level, and skin set in a child portlet ");
187         print("and in a child PortletSet.");
188         print("RESULT: Un-assigned portlets get the top skin.  Assigned portlets get there assigned skin. ");
189         print("Assigned PortletSets use assigned skin and so do their children.");
190         print("");
191         print("Checking test case 3...");
192         File file = createTestProfile(prof3);
193         PSMLDocument doc = getDocumentFromPath(file.getPath());
194         Portlets portlets = doc.getPortlets();
195         print("Portlets loaded as: " + portlets);
196 
197         print("Save and re-open document as if it were being loaded for the first time...");
198         saveDocument(doc);
199         // re-load everything...
200         doc = null;
201         doc = getDocumentFromPath(file.getPath());
202         portlets = doc.getPortlets();
203 
204         print("Using the PortalToolkit.  All Portlets and PsmlEntries (individual portlets) ");
205 
206         PortletSet pSet = PortalToolkit.getSet(portlets);
207         assertNotNull(pSet);
208 
209         // Checking if we are at the root
210         isRoot(pSet);
211         HashMap settingsMap = new HashMap();
212         settingsMap.put("01", new MatchSettings(false, false, "grey", true));
213         settingsMap.put("02", new MatchSettings(false, true, null, false));
214         settingsMap.put("03", new MatchSettings(false, false, "BorderedTitleStylesOnly", true));
215         settingsMap.put("04", new MatchSettings(false, false, "StylesOnly", true));
216         settingsMap.put("05", new MatchSettings(false, true, null, false));
217         settingsMap.put("06", new MatchSettings(false, true, null, false));
218         settingsMap.put("07", new MatchSettings(false, true, null, false));
219         settingsMap.put("08", new MatchSettings(false, true, null, false));
220 
221         checkPortletSkinValues(pSet, settingsMap, doc);
222         printOk();
223 
224         printDivider();
225     }
226     
227     /***
228      * Case 4
229       */
230     public void testCase4()
231     {
232         printDivider();
233         print("Description: Skin NOT set at top level, and skin set in a child portlet ");
234         print("and in a child PortletSet.");
235         print("RESULT: Un-assigned portlets use the system default skin.  Assigned portlets get there assigned skin. ");
236         print("Assigned PortletSets use assigned skin and so do their children.");
237         print("");
238         print("Checking test case 4...");
239         File file = createTestProfile(prof4);
240         PSMLDocument doc = getDocumentFromPath(file.getPath());
241         Portlets portlets = doc.getPortlets();
242         print("Portlets loaded as: " + portlets);
243 
244 
245         print("Save and re-open document as if it were being loaded for the first time...");
246         saveDocument(doc);
247         // re-load everything...
248         doc = null;
249         doc = getDocumentFromPath(file.getPath());
250         portlets = doc.getPortlets();
251 
252         print("Using the PortalToolkit.  All Portlets and PsmlEntries (individual portlets) ");
253 
254         PortletSet pSet = PortalToolkit.getSet(portlets);
255         assertNotNull(pSet);
256 
257         // Checking if we are at the root
258         isRoot(pSet);
259         HashMap settingsMap = new HashMap();
260         settingsMap.put("01", new MatchSettings(true, false, null, false));
261         settingsMap.put("02", new MatchSettings(false, false, "grey", true));
262         settingsMap.put("03", new MatchSettings(false, true, null, false));
263         settingsMap.put("04", new MatchSettings(false, false, null, false));
264         settingsMap.put("05", new MatchSettings(true, true, null, false));
265         settingsMap.put("06", new MatchSettings(false, false, "StylesOnly", true));
266         settingsMap.put("07", new MatchSettings(true, true, null, false));
267         settingsMap.put("08", new MatchSettings(true, true, null, false));
268 
269         checkPortletSkinValues(pSet, settingsMap, doc);
270         printOk();
271 
272         printDivider();
273     }
274     
275      /***
276      * Case 5
277       */
278     public void testCase5()
279     {
280         printDivider();
281         print("Description: Test that, when setting the root skin and saving that no other ");
282         print("Portlets get a skin written.");
283         print("RESULT: Only the root is assigned the selected skin");
284 
285         print("");
286         print("Checking test case 5...");
287         File file = createTestProfile(prof1);
288         PSMLDocument doc = getDocumentFromPath(file.getPath());
289         Portlets portlets = doc.getPortlets();
290         print("Portlets loaded as: " + portlets);
291 
292         print("Directly setting the rootSet to a \"grey\"...");
293         Skin rootSkin = new PsmlSkin();
294         rootSkin.setName("grey");
295         portlets.setSkin(rootSkin);
296         print("Save and re-open document as if it were being loaded for the first time...");
297         saveDocument(doc);
298         // re-load everything...
299         doc = null;
300         doc = getDocumentFromPath(file.getPath());
301         portlets = doc.getPortlets();
302 
303         print("Using the PortalToolkit.  All Portlets and PsmlEntries (individual portlets) ");
304 
305         PortletSet pSet = PortalToolkit.getSet(portlets);
306         assertNotNull(pSet);
307 
308         // Checking if we are at the root
309         isRoot(pSet);
310         HashMap settingsMap = new HashMap();
311         settingsMap.put("01", new MatchSettings(true, false, "grey", true));
312         
313         checkPortletSkinValues(pSet, settingsMap, doc);
314         printOk();
315 
316         printDivider();
317     }
318 
319     /***
320      * Walks the PSML document tree and checks each Portlet/PortletSet
321      * for correct skin settings based on the MatchSettings provided.
322      */
323     protected void checkPortletSkinValues(PortletSet pSet, HashMap settingsMap, PSMLDocument doc)
324     {
325         // Check that we are using the default skin as defined by the system
326 
327         performCheck(pSet, doc, null, (MatchSettings) settingsMap.get(pSet.getID()), null);
328 
329         Enumeration enum = pSet.getPortlets();
330         while (enum.hasMoreElements())
331         {
332             PortletSet subSet = (PortletSet) enum.nextElement();
333             performCheck(subSet, doc, pSet, (MatchSettings) settingsMap.get(subSet.getID()), "  |--- ");
334 
335             Enumeration singleEnum = subSet.getPortlets();
336             print("  |--- Checking individual portlets for PortletSet " + getNameTag(subSet) + "...");
337             while (singleEnum.hasMoreElements())
338             {
339                 Portlet portlet = (Portlet) singleEnum.nextElement();
340                 performCheck(portlet, doc, subSet, (MatchSettings) settingsMap.get(portlet.getID()), "  |    |--- ");
341             }
342         }
343     }
344 
345     protected void isRoot(PortletSet pSet)
346     {
347         print("Checking PortletSet is root...");
348         print("PortletSet ID: " + pSet.getID());
349         print("PortletSet name: " + pSet.getName());
350         assertTrue(pSet.getID().equals("01"));
351         assertTrue(pSet.getName().equals("theRootSet"));
352         printOk();
353     }
354 
355     /***
356      * Checks for the physical presence of skins.
357      * portlet id's within  the list should have skins
358      * while those not in the list should NOT have skins.
359      * A null list means that ALL skins should be unset.
360      * 
361      */
362     protected void checkSkinPresence(Portlets portlets, List idsWithSkins)
363     {
364 
365         assertNotNull(portlets);
366         printOk();
367 
368         print("Verify all skins presence for this profile...");
369         if (idsWithSkins == null || !idsWithSkins.contains(portlets.getId()))
370         {
371             print("Verify that root *DOES NOT* have a skin set...");
372             assertNull(portlets.getSkin());
373         }
374         else
375         {
376             print("Verify that root *DOES* have a skin set...");
377             assertNotNull(portlets.getSkin());
378         }
379         printOk();
380 
381         Iterator itr = portlets.getPortletsIterator();
382         while (itr.hasNext())
383         {
384             Portlets childPortlets = (Portlets) itr.next();
385             if (idsWithSkins == null || !idsWithSkins.contains(childPortlets.getId()))
386             {
387                 print("Verify skin *IS NOT* set for Portlets " + getNameTag(childPortlets) + "...");
388                 assertNull(childPortlets.getSkin());
389             }
390             else
391             {
392                 print("Verify skin *IS* set for Portlets " + getNameTag(childPortlets) + "...");
393                 assertNotNull(childPortlets.getSkin());
394             }
395             printOk();
396 
397             Iterator pItr = childPortlets.getEntriesIterator();
398             while (pItr.hasNext())
399             {
400                 PsmlEntry entry = (PsmlEntry) pItr.next();
401 
402                 if (idsWithSkins == null || !idsWithSkins.contains(entry.getId()))
403                 {
404                     print("Verify skin *IS NOT* set for portlet " + getNameTag(entry) + "...");
405                     assertNull(entry.getSkin());
406                 }
407                 else
408                 {
409                     print("Verify skin *IS* set for portlet " + getNameTag(entry) + "...");
410                     assertNotNull(entry.getSkin());
411                 }
412                 printOk();
413             }
414         }
415     }
416 
417     protected boolean matchesParentSkin(Portlet portlet, Portlet parent)
418     {
419         String parentSkin = parent.getPortletConfig().getPortletSkin().getName();
420         return matchesSkin(portlet, parentSkin);
421     }
422 
423     protected boolean matchesDefaultSkin(Portlet portlet)
424     {
425         return matchesSkin(portlet, this.defaultSkin);
426     }
427 
428     protected boolean matchesSkin(Portlet portlet, String skinName)
429     {
430         String mySkin = portlet.getPortletConfig().getPortletSkin().getName();
431         return mySkin.equals(skinName);
432     }
433 
434 	/***
435 	 * Performs skin checks for a portlet based on the MatchSettings 
436 	 * associated with it
437 	 */
438     protected void performCheck(Portlet portlet, PSMLDocument doc, Portlet parent, MatchSettings settings, String linePrefix)
439     {
440 
441         boolean isRoot = (parent == null);
442         if (linePrefix == null)
443             linePrefix = "";
444 
445         IdentityElement element = doc.getPortletsById(portlet.getID());
446         if (element == null)
447             element = doc.getEntryById(portlet.getID());
448 
449         print(linePrefix + "Verify a corresponding IdentitiyElement for " + getNameTag(portlet));
450         assertNotNull(element);
451         printOk(linePrefix);
452 
453         // automatic settings for a "virgin" skin settings
454         if (settings == null)
455             settings = new MatchSettings(true, true, null, false);
456 
457         if (settings.isSkinPresent())
458         {
459             print(linePrefix + "Verify skin *IS* set for  IdentitiyElement " + getNameTag(element) + "...");
460             assertNotNull(element.getSkin());
461             printOk(linePrefix);
462         }
463         else
464         {
465             print(linePrefix + "Verify skin *IS NOT* set for  IdentitiyElement " + getNameTag(element) + "...");
466             Skin showSkin = element.getSkin();
467             assertNull(element.getSkin());
468             printOk(linePrefix);
469         }
470 
471         if (!isRoot && settings.matchParentSkin())
472         {
473             print(linePrefix + "Verify that Portlet " + getNameTag(portlet) + "'s skin matches it's parent's, " + getNameTag(parent) + " skin...");
474             assertNotNull(parent);
475             matchesParentSkin(portlet, parent);
476             printOk(linePrefix);
477         }
478 
479         if (settings.matchDefaultSkin())
480         {
481             print(linePrefix + "Verify that Portlet " + getNameTag(portlet) + "'s skin  matches the default skin...");
482             matchesDefaultSkin(portlet);
483             printOk(linePrefix);
484         }
485 
486         if (settings.getSkin() != null)
487         {
488             print(linePrefix + "Verify that Portlet " + getNameTag(portlet) + "'s skin  uses the skin " + settings.getSkin() + "...");
489             matchesSkin(portlet, settings.getSkin());
490             printOk(linePrefix);
491         }
492 
493     }
494 
495     /***
496     * Creates the test suite.
497     *
498     * @return a test suite (<code>TestSuite</code>) that includes all methods
499     *         starting with "test"
500     */
501     public static Test suite()
502     {
503         // All methods starting with "test" will be executed in the test suite.
504         return new TestSuite(TestSkinAggregation.class);
505     }
506 
507     public static void main(String[] args)
508     {
509         junit.awtui.TestRunner.main(new String[] { TestSkinAggregation.class.getName()});
510     }
511 
512     protected File createTestProfile(File base)
513     {
514         File testFile = null;
515         BufferedReader reader = null;
516         BufferedWriter writer = null;
517 
518         try
519         {
520             String testDir = base.getParent();
521             String testFilePath = testDir + File.separator + "working_" + base.getName();
522             testFile = new File(testFilePath);
523             if (testFile.exists())
524                 testFile.delete();
525             else
526                 testFile.createNewFile();
527 
528             reader = new BufferedReader(new FileReader(base));
529             writer = new BufferedWriter(new FileWriter(testFile));
530             String line;
531             while ((line = reader.readLine()) != null)
532             {
533                 writer.write(line);
534             }
535             // make sure we write the file
536             writer.flush();
537         }
538         catch (Exception e)
539         {
540             e.printStackTrace();
541             testResult.addError(this, new NestableException("Unable to build workin file for skin test.", e));
542         }
543         finally
544         {
545             try
546             {
547                 if (reader != null)
548                     reader.close();
549 
550                 if (writer != null)
551                     writer.close();
552             }
553             catch (IOException e)
554             {
555                 // let it go
556             }
557         }
558 
559         return testFile;
560 
561     }
562 
563     /***
564      * @see junit.framework.TestCase#setUp()
565      */
566     protected void setUp() throws Exception
567     {
568         super.setUp();
569 
570         ResourceService serviceConf = ((TurbineServices) TurbineServices.getInstance()).getResources(PortalToolkitService.SERVICE_NAME);
571 
572         this.defaultSkin = serviceConf.getString("default.skin");
573         String path = getTestConfig().getString(SKIN_TEST_PATH);
574         String path2 = getTestConfig().getString(SKIN_TEST2_PATH);
575         String path3 = getTestConfig().getString(SKIN_TEST3_PATH);
576         String path4 = getTestConfig().getString(SKIN_TEST4_PATH);
577         prof1 = new File(path);
578         prof2 = new File(path2);
579         prof3 = new File(path3);
580         prof4 = new File(path4);
581     }
582 
583     protected boolean usesDefaultSkin(Portlet portlet)
584     {
585 
586         return portlet.getPortletConfig().getPortletSkin().getName().equals(this.defaultSkin);
587     }
588 
589     protected String getNameTag(Portlet portlet)
590     {
591         return "Id: " + portlet.getID() + " Name: " + portlet.getName();
592     }
593 
594     protected String getNameTag(IdentityElement el)
595     {
596         return "Id: " + el.getId() + " Name: " + el.getName();
597     }
598 
599 	/***
600 	 * Allows setting of matching criteria for individual portlet
601 	 * entries
602 	 */	
603     class MatchSettings
604     {
605         private boolean defaultSkin;
606         private boolean parentSkin;
607         private String skin;
608         private boolean skinPresent;
609 
610         public MatchSettings(boolean defaultSkin, boolean parentSkin, String skin, boolean skinPresent)
611         {
612             this.defaultSkin = defaultSkin;
613             this.parentSkin = parentSkin;
614             this.skin = skin;
615             this.skinPresent = skinPresent;
616         }
617 
618         /***
619          * Returns the defaultSkin.
620          * @return boolean
621          */
622         public boolean matchDefaultSkin()
623         {
624             return defaultSkin;
625         }
626 
627         /***
628          * Returns the parentSkin.
629          * @return boolean
630          */
631         public boolean matchParentSkin()
632         {
633             return parentSkin;
634         }
635 
636         /***
637          * Returns the skin.
638          * @return String
639          */
640         public String getSkin()
641         {
642             return skin;
643         }
644 
645         /***
646          * Sets the defaultSkin.
647          * @param defaultSkin The defaultSkin to set
648          */
649         public void setDefaultSkin(boolean defaultSkin)
650         {
651             this.defaultSkin = defaultSkin;
652         }
653 
654         /***
655          * Sets the parentSkin.
656          * @param parentSkin The parentSkin to set
657          */
658         public void setParentSkin(boolean parentSkin)
659         {
660             this.parentSkin = parentSkin;
661         }
662 
663         /***
664          * Sets the skin.
665          * @param skin The skin to set
666          */
667         public void setSkin(String skin)
668         {
669             this.skin = skin;
670         }
671         /***
672          * Returns the skinPresent.
673          * @return boolean
674          */
675         public boolean isSkinPresent()
676         {
677             return skinPresent;
678         }
679 
680         /***
681          * Sets the skinPresent. Specifies whether or not this
682          * Portlet's PsmlDocument Entry should have a skin
683          * assigned to it.
684          * @param skinPresent The skinPresent to set
685          */
686         public void setSkinPresent(boolean skinPresent)
687         {
688             this.skinPresent = skinPresent;
689         }
690 
691     }
692 
693 }