/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Jetspeed" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache" or
* "Apache Jetspeed", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.jetspeed.services.portaltoolkit;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.commons.lang.exception.NestableException;
import org.apache.jetspeed.om.profile.IdentityElement;
import org.apache.jetspeed.om.profile.PSMLDocument;
import org.apache.jetspeed.om.profile.Portlets;
import org.apache.jetspeed.om.profile.Skin;
import org.apache.jetspeed.om.profile.psml.PsmlEntry;
import org.apache.jetspeed.om.profile.psml.PsmlSkin;
import org.apache.jetspeed.portal.Portlet;
import org.apache.jetspeed.portal.PortletSet;
import org.apache.jetspeed.services.PortalToolkit;
import org.apache.jetspeed.test.HeadlessBaseTest;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.resources.ResourceService;
/**
* @author <a href="mailto:sweaver@rippe.com">Scott Weaver</a>
* Tests different use cases of what happens when skins are requested
* /applied.
*
*/
public class TestSkinAggregation extends HeadlessBaseTest
{
public static String SKIN_TEST_PATH = "skin.test";
public static String SKIN_TEST2_PATH = "skin.test2";
public static String SKIN_TEST3_PATH = "skin.test3";
public static String SKIN_TEST4_PATH = "skin.test4";
private File prof1;
private File prof2;
private File prof3;
private File prof4;
private String defaultSkin;
public TestSkinAggregation(String name)
{
super(name);
}
/**
* 1) no skin ref in PSML
* RESULT: uses default skin
*
* This tests to see that, when no skin is defined, the default skin is
* used.
*/
public void testCase1()
{
printDivider();
print("Description: No skin set in PSML ");
print("RESULT: All portlets use the system default skin.");
print("Checking test case 1...");
File file = createTestProfile(prof1);
PSMLDocument doc = getDocumentFromPath(file.getPath());
Portlets portlets = doc.getPortlets();
print("Portlets loaded as: " + portlets);
// checkSkinPresence(portlets, null);
print("Using the PortalToolkit. All Portlets and PsmlEntries (individual portlets) ");
print("should now be using the system default skin, " + this.defaultSkin);
PortletSet pSet = PortalToolkit.getSet(portlets);
assertNotNull(pSet);
// Checking if we are at the root
isRoot(pSet);
checkPortletSkinValues(pSet, new HashMap(), doc);
print("Saving test document...");
saveDocument(doc);
printOk();
print("Re-run check to make sure that the default setting did not get written...");
PSMLDocument doc2 = getDocumentFromPath(file.getPath());
Portlets portlets2 = doc.getPortlets();
PortletSet pSet2 = PortalToolkit.getSet(portlets2);
checkPortletSkinValues(pSet2, new HashMap(), doc2);
printDivider();
}
/**
* Checks if the file path of skin.test exists and is accessable
*/
public void testLoadSkinPath()
{
printDivider();
print("Checking skin test profile...");
assertTrue(prof1.exists());
assertTrue(prof2.exists());
print("Found skin test profile at: " + prof1.getPath());
printDivider();
}
/**
* 1) no skin ref in PSML
* RESULT: uses default skin
*
* This tests to see that, when no skin is defined, the default skin is
* used.
*/
public void testCase2()
{
printDivider();
print("Description: Skin set at root level, skin set in any children.");
print("RESULT: All portlets use the root level skin");
print("Checking test case 2...");
File file = createTestProfile(prof2);
PSMLDocument doc = getDocumentFromPath(file.getPath());
Portlets portlets = doc.getPortlets();
print("Portlets loaded as: " + portlets);
print("Save and re-open document as if it were being loaded for the first time...");
saveDocument(doc);
// re-load everything...
doc = null;
doc = getDocumentFromPath(file.getPath());
portlets = doc.getPortlets();
print("Using the PortalToolkit. All Portlets and PsmlEntries (individual portlets) ");
PortletSet pSet = PortalToolkit.getSet(portlets);
assertNotNull(pSet);
// Checking if we are at the root
isRoot(pSet);
HashMap settingsMap = new HashMap();
settingsMap.put(portlets.getId(), new MatchSettings(false, false, "grey", true));
settingsMap.put("02", new MatchSettings(false, true, null, false));
settingsMap.put("03", new MatchSettings(false, true, null, false));
settingsMap.put("04", new MatchSettings(false, true, null, false));
settingsMap.put("05", new MatchSettings(false, true, null, false));
settingsMap.put("06", new MatchSettings(false, true, null, false));
settingsMap.put("07", new MatchSettings(false, true, null, false));
settingsMap.put("08", new MatchSettings(false, true, null, false));
checkPortletSkinValues(pSet, settingsMap, doc);
printOk();
printDivider();
}
/**
* Case 3
*/
public void testCase3()
{
printDivider();
print("Description: Skin set at top level, and skin set in a child portlet ");
print("and in a child PortletSet.");
print("RESULT: Un-assigned portlets get the top skin. Assigned portlets get there assigned skin. ");
print("Assigned PortletSets use assigned skin and so do their children.");
print("");
print("Checking test case 3...");
File file = createTestProfile(prof3);
PSMLDocument doc = getDocumentFromPath(file.getPath());
Portlets portlets = doc.getPortlets();
print("Portlets loaded as: " + portlets);
print("Save and re-open document as if it were being loaded for the first time...");
saveDocument(doc);
// re-load everything...
doc = null;
doc = getDocumentFromPath(file.getPath());
portlets = doc.getPortlets();
print("Using the PortalToolkit. All Portlets and PsmlEntries (individual portlets) ");
PortletSet pSet = PortalToolkit.getSet(portlets);
assertNotNull(pSet);
// Checking if we are at the root
isRoot(pSet);
HashMap settingsMap = new HashMap();
settingsMap.put("01", new MatchSettings(false, false, "grey", true));
settingsMap.put("02", new MatchSettings(false, true, null, false));
settingsMap.put("03", new MatchSettings(false, false, "BorderedTitleStylesOnly", true));
settingsMap.put("04", new MatchSettings(false, false, "StylesOnly", true));
settingsMap.put("05", new MatchSettings(false, true, null, false));
settingsMap.put("06", new MatchSettings(false, true, null, false));
settingsMap.put("07", new MatchSettings(false, true, null, false));
settingsMap.put("08", new MatchSettings(false, true, null, false));
checkPortletSkinValues(pSet, settingsMap, doc);
printOk();
printDivider();
}
/**
* Case 4
*/
public void testCase4()
{
printDivider();
print("Description: Skin NOT set at top level, and skin set in a child portlet ");
print("and in a child PortletSet.");
print("RESULT: Un-assigned portlets use the system default skin. Assigned portlets get there assigned skin. ");
print("Assigned PortletSets use assigned skin and so do their children.");
print("");
print("Checking test case 4...");
File file = createTestProfile(prof4);
PSMLDocument doc = getDocumentFromPath(file.getPath());
Portlets portlets = doc.getPortlets();
print("Portlets loaded as: " + portlets);
print("Save and re-open document as if it were being loaded for the first time...");
saveDocument(doc);
// re-load everything...
doc = null;
doc = getDocumentFromPath(file.getPath());
portlets = doc.getPortlets();
print("Using the PortalToolkit. All Portlets and PsmlEntries (individual portlets) ");
PortletSet pSet = PortalToolkit.getSet(portlets);
assertNotNull(pSet);
// Checking if we are at the root
isRoot(pSet);
HashMap settingsMap = new HashMap();
settingsMap.put("01", new MatchSettings(true, false, null, false));
settingsMap.put("02", new MatchSettings(false, false, "grey", true));
settingsMap.put("03", new MatchSettings(false, true, null, false));
settingsMap.put("04", new MatchSettings(false, false, null, false));
settingsMap.put("05", new MatchSettings(true, true, null, false));
settingsMap.put("06", new MatchSettings(false, false, "StylesOnly", true));
settingsMap.put("07", new MatchSettings(true, true, null, false));
settingsMap.put("08", new MatchSettings(true, true, null, false));
checkPortletSkinValues(pSet, settingsMap, doc);
printOk();
printDivider();
}
/**
* Case 5
*/
public void testCase5()
{
printDivider();
print("Description: Test that, when setting the root skin and saving that no other ");
print("Portlets get a skin written.");
print("RESULT: Only the root is assigned the selected skin");
print("");
print("Checking test case 5...");
File file = createTestProfile(prof1);
PSMLDocument doc = getDocumentFromPath(file.getPath());
Portlets portlets = doc.getPortlets();
print("Portlets loaded as: " + portlets);
print("Directly setting the rootSet to a \"grey\"...");
Skin rootSkin = new PsmlSkin();
rootSkin.setName("grey");
portlets.setSkin(rootSkin);
print("Save and re-open document as if it were being loaded for the first time...");
saveDocument(doc);
// re-load everything...
doc = null;
doc = getDocumentFromPath(file.getPath());
portlets = doc.getPortlets();
print("Using the PortalToolkit. All Portlets and PsmlEntries (individual portlets) ");
PortletSet pSet = PortalToolkit.getSet(portlets);
assertNotNull(pSet);
// Checking if we are at the root
isRoot(pSet);
HashMap settingsMap = new HashMap();
settingsMap.put("01", new MatchSettings(true, false, "grey", true));
checkPortletSkinValues(pSet, settingsMap, doc);
printOk();
printDivider();
}
/**
* Walks the PSML document tree and checks each Portlet/PortletSet
* for correct skin settings based on the MatchSettings provided.
*/
protected void checkPortletSkinValues(PortletSet pSet, HashMap settingsMap, PSMLDocument doc)
{
// Check that we are using the default skin as defined by the system
performCheck(pSet, doc, null, (MatchSettings) settingsMap.get(pSet.getID()), null);
Enumeration enum = pSet.getPortlets();
while (enum.hasMoreElements())
{
PortletSet subSet = (PortletSet) enum.nextElement();
performCheck(subSet, doc, pSet, (MatchSettings) settingsMap.get(subSet.getID()), " |--- ");
Enumeration singleEnum = subSet.getPortlets();
print(" |--- Checking individual portlets for PortletSet " + getNameTag(subSet) + "...");
while (singleEnum.hasMoreElements())
{
Portlet portlet = (Portlet) singleEnum.nextElement();
performCheck(portlet, doc, subSet, (MatchSettings) settingsMap.get(portlet.getID()), " | |--- ");
}
}
}
protected void isRoot(PortletSet pSet)
{
print("Checking PortletSet is root...");
print("PortletSet ID: " + pSet.getID());
print("PortletSet name: " + pSet.getName());
assertTrue(pSet.getID().equals("01"));
assertTrue(pSet.getName().equals("theRootSet"));
printOk();
}
/**
* Checks for the physical presence of skins.
* portlet id's within the list should have skins
* while those not in the list should NOT have skins.
* A null list means that ALL skins should be unset.
*
*/
protected void checkSkinPresence(Portlets portlets, List idsWithSkins)
{
assertNotNull(portlets);
printOk();
print("Verify all skins presence for this profile...");
if (idsWithSkins == null || !idsWithSkins.contains(portlets.getId()))
{
print("Verify that root *DOES NOT* have a skin set...");
assertNull(portlets.getSkin());
}
else
{
print("Verify that root *DOES* have a skin set...");
assertNotNull(portlets.getSkin());
}
printOk();
Iterator itr = portlets.getPortletsIterator();
while (itr.hasNext())
{
Portlets childPortlets = (Portlets) itr.next();
if (idsWithSkins == null || !idsWithSkins.contains(childPortlets.getId()))
{
print("Verify skin *IS NOT* set for Portlets " + getNameTag(childPortlets) + "...");
assertNull(childPortlets.getSkin());
}
else
{
print("Verify skin *IS* set for Portlets " + getNameTag(childPortlets) + "...");
assertNotNull(childPortlets.getSkin());
}
printOk();
Iterator pItr = childPortlets.getEntriesIterator();
while (pItr.hasNext())
{
PsmlEntry entry = (PsmlEntry) pItr.next();
if (idsWithSkins == null || !idsWithSkins.contains(entry.getId()))
{
print("Verify skin *IS NOT* set for portlet " + getNameTag(entry) + "...");
assertNull(entry.getSkin());
}
else
{
print("Verify skin *IS* set for portlet " + getNameTag(entry) + "...");
assertNotNull(entry.getSkin());
}
printOk();
}
}
}
protected boolean matchesParentSkin(Portlet portlet, Portlet parent)
{
String parentSkin = parent.getPortletConfig().getPortletSkin().getName();
return matchesSkin(portlet, parentSkin);
}
protected boolean matchesDefaultSkin(Portlet portlet)
{
return matchesSkin(portlet, this.defaultSkin);
}
protected boolean matchesSkin(Portlet portlet, String skinName)
{
String mySkin = portlet.getPortletConfig().getPortletSkin().getName();
return mySkin.equals(skinName);
}
/**
* Performs skin checks for a portlet based on the MatchSettings
* associated with it
*/
protected void performCheck(Portlet portlet, PSMLDocument doc, Portlet parent, MatchSettings settings, String linePrefix)
{
boolean isRoot = (parent == null);
if (linePrefix == null)
linePrefix = "";
IdentityElement element = doc.getPortletsById(portlet.getID());
if (element == null)
element = doc.getEntryById(portlet.getID());
print(linePrefix + "Verify a corresponding IdentitiyElement for " + getNameTag(portlet));
assertNotNull(element);
printOk(linePrefix);
// automatic settings for a "virgin" skin settings
if (settings == null)
settings = new MatchSettings(true, true, null, false);
if (settings.isSkinPresent())
{
print(linePrefix + "Verify skin *IS* set for IdentitiyElement " + getNameTag(element) + "...");
assertNotNull(element.getSkin());
printOk(linePrefix);
}
else
{
print(linePrefix + "Verify skin *IS NOT* set for IdentitiyElement " + getNameTag(element) + "...");
Skin showSkin = element.getSkin();
assertNull(element.getSkin());
printOk(linePrefix);
}
if (!isRoot && settings.matchParentSkin())
{
print(linePrefix + "Verify that Portlet " + getNameTag(portlet) + "'s skin matches it's parent's, " + getNameTag(parent) + " skin...");
assertNotNull(parent);
matchesParentSkin(portlet, parent);
printOk(linePrefix);
}
if (settings.matchDefaultSkin())
{
print(linePrefix + "Verify that Portlet " + getNameTag(portlet) + "'s skin matches the default skin...");
matchesDefaultSkin(portlet);
printOk(linePrefix);
}
if (settings.getSkin() != null)
{
print(linePrefix + "Verify that Portlet " + getNameTag(portlet) + "'s skin uses the skin " + settings.getSkin() + "...");
matchesSkin(portlet, settings.getSkin());
printOk(linePrefix);
}
}
/**
* Creates the test suite.
*
* @return a test suite (<code>TestSuite</code>) that includes all methods
* starting with "test"
*/
public static Test suite()
{
// All methods starting with "test" will be executed in the test suite.
return new TestSuite(TestSkinAggregation.class);
}
public static void main(String[] args)
{
junit.awtui.TestRunner.main(new String[] { TestSkinAggregation.class.getName()});
}
protected File createTestProfile(File base)
{
File testFile = null;
BufferedReader reader = null;
BufferedWriter writer = null;
try
{
String testDir = base.getParent();
String testFilePath = testDir + File.separator + "working_" + base.getName();
testFile = new File(testFilePath);
if (testFile.exists())
testFile.delete();
else
testFile.createNewFile();
reader = new BufferedReader(new FileReader(base));
writer = new BufferedWriter(new FileWriter(testFile));
String line;
while ((line = reader.readLine()) != null)
{
writer.write(line);
}
// make sure we write the file
writer.flush();
}
catch (Exception e)
{
e.printStackTrace();
testResult.addError(this, new NestableException("Unable to build workin file for skin test.", e));
}
finally
{
try
{
if (reader != null)
reader.close();
if (writer != null)
writer.close();
}
catch (IOException e)
{
// let it go
}
}
return testFile;
}
/**
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception
{
super.setUp();
ResourceService serviceConf = ((TurbineServices) TurbineServices.getInstance()).getResources(PortalToolkitService.SERVICE_NAME);
this.defaultSkin = serviceConf.getString("default.skin");
String path = getTestConfig().getString(SKIN_TEST_PATH);
String path2 = getTestConfig().getString(SKIN_TEST2_PATH);
String path3 = getTestConfig().getString(SKIN_TEST3_PATH);
String path4 = getTestConfig().getString(SKIN_TEST4_PATH);
prof1 = new File(path);
prof2 = new File(path2);
prof3 = new File(path3);
prof4 = new File(path4);
}
protected boolean usesDefaultSkin(Portlet portlet)
{
return portlet.getPortletConfig().getPortletSkin().getName().equals(this.defaultSkin);
}
protected String getNameTag(Portlet portlet)
{
return "Id: " + portlet.getID() + " Name: " + portlet.getName();
}
protected String getNameTag(IdentityElement el)
{
return "Id: " + el.getId() + " Name: " + el.getName();
}
/**
* Allows setting of matching criteria for individual portlet
* entries
*/
class MatchSettings
{
private boolean defaultSkin;
private boolean parentSkin;
private String skin;
private boolean skinPresent;
public MatchSettings(boolean defaultSkin, boolean parentSkin, String skin, boolean skinPresent)
{
this.defaultSkin = defaultSkin;
this.parentSkin = parentSkin;
this.skin = skin;
this.skinPresent = skinPresent;
}
/**
* Returns the defaultSkin.
* @return boolean
*/
public boolean matchDefaultSkin()
{
return defaultSkin;
}
/**
* Returns the parentSkin.
* @return boolean
*/
public boolean matchParentSkin()
{
return parentSkin;
}
/**
* Returns the skin.
* @return String
*/
public String getSkin()
{
return skin;
}
/**
* Sets the defaultSkin.
* @param defaultSkin The defaultSkin to set
*/
public void setDefaultSkin(boolean defaultSkin)
{
this.defaultSkin = defaultSkin;
}
/**
* Sets the parentSkin.
* @param parentSkin The parentSkin to set
*/
public void setParentSkin(boolean parentSkin)
{
this.parentSkin = parentSkin;
}
/**
* Sets the skin.
* @param skin The skin to set
*/
public void setSkin(String skin)
{
this.skin = skin;
}
/**
* Returns the skinPresent.
* @return boolean
*/
public boolean isSkinPresent()
{
return skinPresent;
}
/**
* Sets the skinPresent. Specifies whether or not this
* Portlet's PsmlDocument Entry should have a skin
* assigned to it.
* @param skinPresent The skinPresent to set
*/
public void setSkinPresent(boolean skinPresent)
{
this.skinPresent = skinPresent;
}
}
}