/* * � Copyright IBM Corp. 2013, 2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ /* * Author: Maire Kehoe (mkehoe@ie.ibm.com) * Date: 28-Jul-2010 */ package com.ibm.xsp.test.framework; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import java.util.Map; import javax.faces.FactoryFinder; import javax.faces.application.Application; import javax.faces.application.ViewHandler; import javax.faces.component.UIViewRoot; import javax.faces.context.FacesContext; import javax.faces.context.FacesContextFactory; import javax.faces.convert.Converter; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ibm.commons.Platform; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.application.ApplicationEx; import com.ibm.xsp.config.BootStrap; import com.ibm.xsp.config.BootStrapFactory; import com.ibm.xsp.context.DojoLibraryFactory; import com.ibm.xsp.controller.FacesController; import com.ibm.xsp.controller.FacesControllerFactory; import com.ibm.xsp.controller.FacesControllerFactoryImpl; import com.ibm.xsp.controller.FacesRequest; import com.ibm.xsp.controller.FacesRequestImpl; import com.ibm.xsp.library.ConfigFileMaintainer; import com.ibm.xsp.library.CoreLibrary; import com.ibm.xsp.library.DirectoryResourceBundleSource; import com.ibm.xsp.library.FacesClassLoader; import com.ibm.xsp.library.LibraryServiceLoader; import com.ibm.xsp.library.LibraryWrapper; import com.ibm.xsp.library.StandardRegistryMaintainer; import com.ibm.xsp.page.PageExtensionUtil; import com.ibm.xsp.page.file.DirectoryFileSystem; import com.ibm.xsp.registry.ComponentDefinitionImpl; import com.ibm.xsp.registry.FacesComplexDefinition; import com.ibm.xsp.registry.FacesComponentDefinition; import com.ibm.xsp.registry.FacesCompositeComponentDefinition; import com.ibm.xsp.registry.FacesDefinition; import com.ibm.xsp.registry.FacesProject; import com.ibm.xsp.registry.FacesSharableRegistry; import com.ibm.xsp.registry.LibraryFragmentImpl; import com.ibm.xsp.registry.SharableRegistryImpl; import com.ibm.xsp.registry.config.FacesClassLoaderFactory; import com.ibm.xsp.registry.config.ResourceBundleSource; import com.ibm.xsp.registry.config.XspRegistryManager; import com.ibm.xsp.registry.config.XspRegistryProvider; import com.ibm.xsp.registry.parse.ConfigParserFactory; import com.ibm.xsp.registry.parse.RegistryAnnotater; import com.ibm.xsp.servlet.local.LocalHttpServletRequest; import com.ibm.xsp.servlet.local.LocalHttpServletResponse; import com.ibm.xsp.servlet.local.LocalServletContext; import com.ibm.xsp.test.framework.render.TestControlInitializer; import com.ibm.xsp.util.SessionUtil; import com.sun.faces.context.FacesContextImpl; @SuppressWarnings("deprecation") public class TestProject { public static final String XSP_CORE_NAMESPACE = "http://www.ibm.com/xsp/core"; public static FacesSharableRegistry createRegistry(AbstractXspTest test) { if( null != test.getTestLocalVars().get("registry") ){ throw new RuntimeException("Registry already exists"); } FacesSharableRegistry registry; // createLocalRegistry // creates the registry ConfigFileMaintainer maintainer; // getUserDir if( ! ConfigUtil.isTargetLocalXspconfigs(test) ){ // should only use the classloader from the target library String libraryId = ConfigUtil.getTargetLibrary(test); boolean isTestJsfHtml = ConfigUtil.isTestJsfHtml(test); boolean isTestAll = ConfigUtil.isTestAll(test); if( null == libraryId && !isTestJsfHtml ){ if( !isTestAll ){ throw new RuntimeException("Not testing local xsp-configs, and not configured to test any library configs, so nothing to test."); } // isTestAll // create a registry with depending on all the libraries FacesSharableRegistry reg = StandardRegistryMaintainer.getStandardRegistry(); // remove the statically cached standard reg: StandardRegistryMaintainer.clearStandardRegistry(); test.getTestLocalVars().put("registry", reg); return reg; } XspRegistryManager manager = XspRegistryManager.getManager(); FacesSharableRegistry libraryReg = null; if( null != libraryId ){ XspRegistryProvider registryProvider = manager.getRegistryProvider(libraryId); if( null != registryProvider ){ libraryReg = registryProvider.getRegistry(); } if( null == libraryReg ){ throw new RuntimeException("Registry not found for libraryId "+libraryId); } } FacesSharableRegistry htmlReg = handleHtmlReg(test); String id = "empty local registry"; SharableRegistryImpl reg = new SharableRegistryImpl(id); reg.setRegistryType(FacesSharableRegistry.TYPE_APPLICATION); // register the project (before this the registry is in an invalid state) reg.createProject(id); // add dependencies if( null != libraryReg ){ for (FacesSharableRegistry libDepend : libraryReg.getDepends()) { reg.addDepend(libDepend); } reg.addDepend(libraryReg); } if( null != htmlReg ){ reg.addDepend(htmlReg); } String[] extraDepends = ConfigUtil.getExtraLibraryDependsDesignTimeNonApplication(test); for (String extraDependId : extraDepends) { XspRegistryProvider registryProvider = manager.getRegistryProvider(extraDependId); if( null == registryProvider ){ throw new RuntimeException("Registry not found for extra libraryId "+extraDependId); } FacesSharableRegistry extraReg = registryProvider.getRegistry(); reg.addDepend(extraReg); } reg.refreshReferences(); test.getTestLocalVars().put("registry", reg); return reg; } // else target local ClassLoader classLoader = test.getClass().getClassLoader(); String dir = System.getProperty("user.dir") + "/"; File userDir = new File(dir); File root = userDir; DirectoryFileSystem fileSystem = DirectoryFileSystem.create(root); // assume xsp-configs translated by custom.xsp-config_en.properties boolean extensionInPropertiesName = true; ResourceBundleSource bundleSource = new DirectoryResourceBundleSource(root, extensionInPropertiesName); FacesClassLoader facesClassLoader = FacesClassLoaderFactory.create(classLoader); maintainer = ConfigFileMaintainer.create( new TestPageConfig(fileSystem, facesClassLoader, bundleSource)); maintainer.init(); registry = maintainer.getRegistry(); if( ConfigUtil.isTestJsfAssignCoreTagNames(test) ){ String coreId = "com.ibm.xsp.core.library"; XspRegistryManager manager = XspRegistryManager.getManager(); FacesSharableRegistry coreReg = manager.getRegistryProvider(coreId).getRegistry(); assignTagName(coreReg, "javax.faces.ViewRoot", "view"); assignTagName(coreReg, "javax.faces.SelectItem", "selectItem"); assignTagName(coreReg, "javax.faces.SelectItems", "selectItems"); } FacesSharableRegistry riReg = handleHtmlReg(test); if( null != riReg && ! registry.getDepends().contains(riReg ) ){ throw new RuntimeException("Testing local project and RI configs but local proj xsp.properties does not depend on RI library."); } test.getTestLocalVars().put("registry", registry); return registry; } private static FacesSharableRegistry handleHtmlReg( AbstractXspTest test) { FacesSharableRegistry riReg = null; if(ConfigUtil.isTestJsfHtml(test) ){ XspRegistryManager manager = XspRegistryManager.getManager(); riReg = manager.getRegistryProvider("com.ibm.xsp.core-html.library").getRegistry(); if( null == riReg ){ throw new RuntimeException("Could not find JSF html library registry."); } } return riReg; } private static void assignTagName(FacesSharableRegistry coreReg, String componentType, String newTagName) { // find the component with the given compType ComponentDefinitionImpl comp = (ComponentDefinitionImpl) coreReg.findDef( componentType); // remove it from it's fragment LibraryFragmentImpl frag = (LibraryFragmentImpl) comp.getFile(); frag.remove(comp); // set it's tag-name (which changes it's id) comp.setTagName(newTagName); // register it again, using the new id. frag.register(comp); } // public static FacesSharableRegistry getTargetRegistry(AbstractXspTest test){ // String targetLibId = ConfigUtil.getTargetLibrary(test); // if( null == targetLibId ){ // throw new RuntimeException("No target library"); // } // FacesSharableRegistry reg = getRegistry(test); // for (FacesSharableRegistry depend : reg.getDepends()) { // if( depend.getId().equals(targetLibId) ){ // return depend; // } // } // throw new RuntimeException("Target library registry not found for "+targetLibId); // } // public static FacesSharableRegistry getTargetRegistry(AbstractXspTest test){ // String targetLibId = ConfigUtil.getTargetLibrary(test); // if( null == targetLibId ){ // throw new RuntimeException("No target library"); // } // FacesSharableRegistry reg = getRegistry(test); // for (FacesSharableRegistry depend : reg.getDepends()) { // if( depend.getId().equals(targetLibId) ){ // return depend; // } // } // throw new RuntimeException("Target library registry not found for "+targetLibId); // } public static List<FacesDefinition> getDefinitions(FacesSharableRegistry reg, AbstractXspTest test){ return getLibDefinitions(reg, test); } public static List<FacesProject> getLibProjects(FacesSharableRegistry reg, AbstractXspTest test) { List<FacesProject> projs = new ArrayList<FacesProject>(); String libraryId = ConfigUtil.getTargetLibrary(test); if( null != libraryId ){ boolean libraryFound = false; for (FacesSharableRegistry depend : reg.getDepends()) { if( libraryId.equals(depend.getId()) ){ libraryFound = true; projs.addAll(depend.getLocalProjectList()); break; } } if( ! libraryFound ){ throw new RuntimeException("library not found: "+libraryId); } } boolean isTestJsfHtml = ConfigUtil.isTestJsfHtml(test); if( isTestJsfHtml ){ String htmlId = "com.ibm.xsp.core-html.library"; boolean htmlFound = false; for (FacesSharableRegistry depend : reg.getDepends()) { if( htmlId.equals(depend.getId()) ){ htmlFound = true; projs.addAll(depend.getLocalProjectList()); break; } } if( ! htmlFound ){ throw new RuntimeException("library not found: "+htmlId); } } boolean isTargetLocalXspconfigs = ConfigUtil.isTargetLocalXspconfigs(test); if( isTargetLocalXspconfigs ){ projs.addAll(reg.getLocalProjectList()); } if( null == libraryId && !isTestJsfHtml && ! isTargetLocalXspconfigs ){ if( !ConfigUtil.isTestAll(test) ){ throw new RuntimeException("Not testing local xsp-configs, and not configured to test any library configs, so nothing to test."); }// else projs.addAll(reg.getProjectList()); } return projs; } public static List<FacesDefinition> getLibDefinitions(FacesSharableRegistry reg, AbstractXspTest test){ List<FacesDefinition> defs = new ArrayList<FacesDefinition>(); for (FacesProject proj : getLibProjects(reg, test)) { FacesSharableRegistry subReg = (FacesSharableRegistry) proj.getRegistry(); List<FacesDefinition> localDefs = subReg.findLocalDefs(); defs.removeAll(localDefs); defs.addAll(localDefs); } return defs; } public static List<FacesDefinition> getComponentsAndComplexes(FacesSharableRegistry reg, AbstractXspTest test){ return getLibCompComplexDefs(reg, test); } public static List<FacesDefinition> getLibCompComplexDefs(FacesSharableRegistry reg, AbstractXspTest test){ List<FacesDefinition> defs = getDefinitions(reg, test); for (int i = 0; i < defs.size(); ) { FacesDefinition def = defs.get(i); if( def instanceof FacesComponentDefinition || def instanceof FacesComplexDefinition ){ i++; }else{ defs.remove(i); } } return defs; } @SuppressWarnings("unchecked") public static List<FacesComponentDefinition> getLibComponents(FacesSharableRegistry reg, AbstractXspTest test){ List<? extends FacesDefinition> defs = getDefinitions(reg, test); for (int i = 0; i < defs.size(); ) { FacesDefinition def = defs.get(i); if( def instanceof FacesComponentDefinition){ i++; }else{ defs.remove(i); } } return (List<FacesComponentDefinition>) defs; }@SuppressWarnings("unchecked") public static List<FacesComplexDefinition> getLibComplexDefs(FacesSharableRegistry reg, AbstractXspTest test){ List<? extends FacesDefinition> defs = getDefinitions(reg, test); for (int i = 0; i < defs.size(); ) { FacesDefinition def = defs.get(i); if( def instanceof FacesComplexDefinition){ i++; }else{ defs.remove(i); } } return (List<FacesComplexDefinition>) defs; } public static FacesContext createFacesContext(AbstractXspTest test) throws Exception{ HttpServletRequest request = createRequest(test, "/xsp/basic.xsp", null); return createFacesContext(test, request); } public static FacesContext createFacesContext(AbstractXspTest test, HttpServletRequest request) throws Exception { FacesController controller = (FacesController) test.getTestLocalVars().get("controller"); if( null == controller ){ bootstrap(test); controller = (FacesController) test.getTestLocalVars().get("controller"); } LocalServletContext servletContext = (LocalServletContext) test.getTestLocalVars().get("servletContext"); HttpServletResponse response = new LocalHttpServletResponse(servletContext, null); FacesContextFactory factory1 = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY); FacesContext context = factory1.getFacesContext(servletContext, request, response, controller.getLifecycle()); String sessionId = request.getSession().getId(); SessionUtil.setSessionId(context, sessionId); test.getTestLocalVars().put("facesContext", context); return context; } /** * Note, usually if extraParams are passed, they should contain ("view:_id1", ""), representing the form control. */ @SuppressWarnings("unchecked") //$NON-NLS-1$ public static HttpServletRequest createRequest(AbstractXspTest test, String viewName, Map<String,String> extraParams) throws Exception{ if( null == test.getTestLocalVars().get("controller") ){ bootstrap(test); } LocalServletContext servletContext = (LocalServletContext) test.getTestLocalVars().get("servletContext"); // HttpServletRequest request = (HttpServletRequest) createServletRequest(); FacesRequestImpl request; try { request = new FacesRequestImpl(viewName, FacesRequest.GET); } catch (MalformedURLException e) { e.printStackTrace(); throw new RuntimeException(e.getMessage(), e); } if( null != extraParams ){ Map<String,String> params = request.getParameters(); params.putAll(extraParams); } HttpServletRequest request2 = new LocalHttpServletRequest(servletContext, request); return request2; } private static void bootstrap(AbstractXspTest test) throws Exception { //TestUtil.getUserDir() String dir = System.getProperty("user.dir") + "/"; File fileSystem = new File(dir); // _servletContext = TestUtil.createServletContext(TestUtil.getUserDir()); // the libraries that have the faces-config paths we want to register List<String> runtimeLibraryIds = findRuntimeLibraryIds(test); // the CLBootStrap constructor always loads all the global library faces-config paths List<String> unexpectedGlobals; List<String> globalLibraryIds = new ArrayList<String>(); { for (LibraryWrapper globalLib : LibraryServiceLoader.getGlobalLibraryServices()) { globalLibraryIds.add(globalLib.getLibraryId()); } List<String> tmp = new ArrayList<String>(globalLibraryIds); tmp.removeAll(runtimeLibraryIds); unexpectedGlobals = tmp; } if( !unexpectedGlobals.isEmpty() ){ throw new RuntimeException("Unexpected global libraryIds " +"not configured in config.properties, but found through environment libs: " +XspTestUtil.concatStrings(StringUtil.toStringArray(unexpectedGlobals))); } // the CLBootStrap will load the extra library's faces-config paths in the init(servletContext) method List<String> requiredExtra; { List<String> tmp= new ArrayList<String>(runtimeLibraryIds); tmp.removeAll(globalLibraryIds); requiredExtra = tmp; } String extraDepends = XspTestUtil.concatStrings(StringUtil.toStringArray(requiredExtra)).replace(" ", ""); // String extraDepends = context.getInitParameter();//$NON-NLS-1$ Hashtable<Object, Object> initParams = new Hashtable<Object, Object>(); initParams.put("xsp.library.extra", extraDepends); LocalServletContext servletContext = new LocalServletContext(fileSystem, initParams); // _bootStrap = BootStrapFactory.createBootStrap(); BootStrap bootStrap = BootStrapFactory.createBootStrap(); bootStrap.init(servletContext); test.getTestLocalVars().put("bootStrap", bootStrap); test.getTestLocalVars().put("servletContext", servletContext); // _controller = createFacesController(_servletContext) FacesControllerFactory factory2; if( runtimeLibraryIds.contains("com.ibm.xsp.designer.library") ){ // if using DesignerApplicationFactoryImpl (referenced from // the designer-faces-config.xml file.): // Set up the ApplicationFinder //ApplicationExecutionContext context = new ApplicationExecutionContext( // testName, TestUtil.getUserDir().getAbsolutePath()); //final Application app = new Application(context); //Application.setApplicationFinder(new Application.IApplicationFinder() { // public Application get() { // return app; // } //}); String testName = null; String userDirPath = getUserDir(test).getAbsolutePath(); ClassLoader classLoader = test.getClass().getClassLoader(); Class<?> appExContextClass = classLoader.loadClass( "com.ibm.designer.runtime.server.util.ApplicationExecutionContext"); Object appExContext = appExContextClass.getConstructor( String.class, String.class).newInstance(testName, userDirPath); Class<?> appClass = classLoader.loadClass("com.ibm.designer.runtime.Application"); Class<?> appExContextInterface = classLoader.loadClass("com.ibm.designer.runtime.IAppExecutionContext"); final Object app =appClass.getConstructor(appExContextInterface).newInstance(appExContext); Class<?> appFinderClass = classLoader.loadClass("com.ibm.designer.runtime.Application$IApplicationFinder"); Object appFinder = java.lang.reflect.Proxy.newProxyInstance(classLoader, new Class[]{appFinderClass}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if( "get".equals(method.getName()) && (null == args || args.length == 0 )){ return app; } return new RuntimeException("unsupported method "+method); } }); appClass.getMethod("setApplicationFinder", appFinderClass).invoke(null, appFinder); // end set up application finder. factory2 = (FacesControllerFactory) Class.forName( "com.ibm.xsp.controller.DesignerFacesControllerFactory") .newInstance(); }else{ factory2 = new FacesControllerFactoryImpl(); } FacesController controller = factory2.createFacesController(servletContext); controller.init(servletContext); test.getTestLocalVars().put("controller", controller); initDojoLibraries(); } /** * @param test * @return */ public static List<String> findRuntimeLibraryIds(AbstractXspTest test) { String libraryId = ConfigUtil.getTargetLibrary(test); List<String> libIds = new ArrayList<String>(); boolean isAddAutoInstalledLibraries; if (ConfigUtil.isLibraryDependsRuntimeAutoInstalledSuppress(test) ){ isAddAutoInstalledLibraries = false; }else if( null == libraryId ){ isAddAutoInstalledLibraries = true; }else{ // if the target library under test is one of the // auto-installed and auto-depended-on libraries, // then do NOT automatically add include all those libraries // - will only use the target&depends and the explicit extra depends boolean isTargetLibraryAutoInstalled; String[] autoInstalledIds = LibraryServiceLoader.getOrderedAutoInstalledLibraryIds(); isTargetLibraryAutoInstalled = (-1 != XspTestUtil.indexOf(autoInstalledIds, libraryId) ); isAddAutoInstalledLibraries = ! isTargetLibraryAutoInstalled; } if( isAddAutoInstalledLibraries ){ // first depend on the XPages runtime library faces-config files String[] autoInstalledIds = LibraryServiceLoader.getOrderedAutoInstalledLibraryIds(); Collections.addAll(libIds, autoInstalledIds); if( null == LibraryServiceLoader.getLibrary("com.ibm.xsp.rcp.library") ){ // The ..xsp.rcp library can be absent in the test environment // and it is not necessarily a problem. libIds.remove("com.ibm.xsp.rcp.library"); } for (String autoInstalledId : libIds) { LibraryWrapper depend = LibraryServiceLoader.getLibrary(autoInstalledId); if( null == depend ){ // &&! "com.ibm.xsp.rcp.library" throw new RuntimeException("autoInstalled library not found: "+autoInstalledId); } } } if (null != libraryId) { LibraryWrapper lib = LibraryServiceLoader.getLibrary(libraryId); if( null == lib ){ throw new RuntimeException( "Could not find the library for target library id " + libraryId + ""); } // Note, DO NOT load all the global libraries // only the auto-installed libraries and the explicitly depended on libraries for (String dependId : lib.getDependencies()) { if( libIds.contains(dependId) ){ continue; } libIds.add(dependId); LibraryWrapper depend = LibraryServiceLoader.getLibrary(dependId); if( null == depend ) throw new NullPointerException(); } libIds.add(libraryId); } String[] extraDependIds = ConfigUtil.getExtraLibraryDependsRuntime(test); for (String extraLibId : extraDependIds) { if( libIds.contains(extraLibId) ){ // if( isAddAutoInstalledLibraries ){ // String[] autoInstalledIds = LibraryServiceLoader.getOrderedAutoInstalledLibraryIds(); // boolean isExtraLibraryAutoInstalled = (-1 != XspTestUtil.indexOf(autoInstalledIds, extraLibId) ); // if( isExtraLibraryAutoInstalled ){ // throw new RuntimeException("extra library depend not needed - already auto-installed: "+extraLibId); // } // } continue; } libIds.add(extraLibId); LibraryWrapper depend = LibraryServiceLoader.getLibrary(extraLibId); if( null == depend ){ throw new RuntimeException("extra library not found: "+extraLibId); } } if( ! libIds.contains(CoreLibrary.LIBRARY_ID) ){ throw new RuntimeException( "Core library neither used by target library nor in extra library depends list"); } return libIds; } /** * @param test * @return */ public static List<String> findFacesConfigPaths(AbstractXspTest test) { List<String> libIds = findRuntimeLibraryIds(test); List<String> facesConfigPaths = new ArrayList<String>(); for (String libId : libIds) { LibraryWrapper lib = LibraryServiceLoader.getLibrary(libId); for (String file : lib.getFacesConfigFiles() ) { facesConfigPaths.add(file); } } return facesConfigPaths; } private static boolean dojoLibrariesInitialized = false; public static void initDojoLibraries() { if( !dojoLibrariesInitialized ){ if(isNotesDLL()) dojoLibrariesInitialized=true; else{ // load the DojoLibraryFactory extension point DojoLibraryFactory.initializeLibraries(); dojoLibrariesInitialized = true; } } } public static boolean isNotesDLL(){ try{ System.loadLibrary("nlsxbe.dll"); return true; } catch (Throwable e){ return false; } } public static UIViewRoot loadEmptyPage(AbstractXspTest test, FacesContext context) throws Exception{ String pageName = "/pages/pregenerated/empty.xsp"; Application application = lazyApplication(test); ViewHandler viewHandler = application.getViewHandler(); UIViewRoot root = viewHandler.createView(context, pageName); if( null == root ){ throw new RuntimeException("JUnit test could not load the empty page "+pageName); } context.setViewRoot(root); return root; } private static Application lazyApplication(AbstractXspTest test) throws Exception{ Application application; if( test.getTestLocalVars().containsKey("application") ){ application = getApplication(test); }else{ application = createApplication(test); } return application; } public static ApplicationEx createApplication( AbstractXspTest test) throws Exception{ FacesController controller = (FacesController) test.getTestLocalVars().get("controller"); if( null == controller ){ bootstrap(test); controller = (FacesController) test.getTestLocalVars().get("controller"); } ApplicationEx application = controller.getApplication(); test.getTestLocalVars().put("application", application); return application; } public static ApplicationEx getApplication( AbstractXspTest test) { ApplicationEx application = (ApplicationEx) test.getTestLocalVars().get("application"); if( null == application ){ throw new RuntimeException("TestUtil.createApplication(AbstractXspTest) has not yet been called"); } return application; } // @SuppressWarnings("unused") // suppression not needed in eclipse 3.6.0 public static void tearDown(AbstractXspTest test){ Map<String, Object> localVars = test.getTestLocalVars(); FacesContext context = (FacesContext) localVars.remove("facesContext"); if( null != context ){ context.setViewRoot(null); new FacesContextImpl(){ { setCurrentInstance(null); } }.getClass(); // call getClass to prevent Object is never used compile warning } FacesController controller = (FacesController) localVars.remove("controller"); if( null != controller){ controller.destroy(); } BootStrap bootstrap = (BootStrap) localVars.remove("bootStrap"); if( null != bootstrap ){ ServletContext servletContext = (ServletContext) localVars.remove("servletContext"); bootstrap.destroy(servletContext); // note, if you don't destroy the bootstrap then // FactoryFinder.getFactory("javax.faces.application.ApplicationFactory"); // hangs around, so the old application instance is used in the next // JUnit test and the managed beans don't resolve. } FacesSharableRegistry registry = (FacesSharableRegistry) localVars.remove("registry"); if( null != registry ){ // prevent unused local variable warning registry.getClass(); } ApplicationEx app = (ApplicationEx) localVars.remove("application"); if( null != app ){ // prevent unused local variable warning app.getClass(); } TestFrameworkPlatform platform = (TestFrameworkPlatform) localVars.remove("platform"); if( null != platform ){ // revert to the previous type of platform - stop using a TestFrameworkPlatform Class<?> defaultPlatformClass = (Class<?>) localVars.remove("platformShadowedClass"); try{ defaultPlatformClass.newInstance(); } catch (Exception e) { throw new RuntimeException("Problem restoring the default platform.", e); } } } public static void initPlatform(AbstractXspTest test, File dominoInstallLocation){ Map<String, Object> localVars = test.getTestLocalVars(); if( null != localVars.get("platform") ){ throw new RuntimeException("Platform already exists"); } Platform defaultPlatformInstance = Platform.getInstance(); Class<?> defaultPlatformClass = defaultPlatformInstance.getClass(); // verify public zero-arg constructor, so will be able to recreate later try { defaultPlatformClass.newInstance(); } catch (Exception e) { throw new RuntimeException("Will not be able to re-set the platform to a "+defaultPlatformClass, e); } TestFrameworkPlatform platform = new TestFrameworkPlatform(dominoInstallLocation); // verify the platform constructor initialized itself as *the* platform if( platform != Platform.getInstance() ){ throw new RuntimeException("Problem setting TestFrameworkPlatform"); } localVars.put("platform", platform); localVars.put("platformShadowedClass", defaultPlatformClass); } public static FacesSharableRegistry getRegistry(AbstractXspTest test){ FacesSharableRegistry reg = (FacesSharableRegistry) test.getTestLocalVars().get("registry"); if( null == reg ){ throw new RuntimeException("TestUtil.createRegistry(AbstractXspTest) has not yet been called"); } return reg; } /** * @param test * @param annotator * @return */ public static FacesSharableRegistry createRegistryWithAnnotater( AbstractXspTest test, RegistryAnnotater ... annotaters) { FacesSharableRegistry reg; // since need to re-parse so the annotater is used, // remove any already-parsed library registries: XspRegistryManager.initManager(null, /*discard*/true); if( null != annotaters ){ for (RegistryAnnotater annotator : annotaters) { ConfigParserFactory.addAnnotater(annotator); } } try{ reg = createRegistry(test); }finally{ if( null != annotaters ){ for (RegistryAnnotater annotator : annotaters) { ConfigParserFactory.removeAnnotater(annotator); } } } return reg; } public static File getUserDir(AbstractXspTest test){ String dir = System.getProperty("user.dir") + "/"; File userDir = new File(dir); return userDir; } public static UIViewRoot loadView(AbstractXspTest test, FacesContext context, String viewId) throws Exception{ String pageName = toPageName(viewId); Application application = lazyApplication(test); ViewHandler viewHandler = application.getViewHandler(); UIViewRoot root = viewHandler.createView(context, pageName); if( null != root ){ context.setViewRoot(root); } return root; } public static String toPageName(String viewName){ if( null == viewName ){ return null; } // /pages/basic -> /pages/basic.xsp viewName = PageExtensionUtil.endWithExtension( viewName ); // pages/basic.xsp -> /pages/basic.xsp if( viewName.charAt(0) != '/' ){ viewName = '/'+viewName; } return viewName; } /** * List all .xsp files in the test's project/plugin, using '/' instead of '\'. * @param test * @return */ public static String[] getAllViewIds(AbstractXspTest test) { return getAllViewIds(test, getUserDir(test)); } /** * List all .xsp files in the test's project/plugin, using '/' instead of '\'. * @param test * @return */ public static String[] getAllViewIds(AbstractXspTest test, File userDir) { FilenameFilter filter = new FilenameFilter() { public boolean accept(File parent, String fileName) { return fileName.endsWith(".xsp"); } }; List<String> fileAbsPaths = new ArrayList<String>(); addFilePaths(userDir, fileAbsPaths, filter); String prefix = userDir.getAbsolutePath(); List<String> viewIds = new ArrayList<String>(); for (String absPath : fileAbsPaths) { String relativePath = absPath.substring(prefix.length()); relativePath = relativePath.replace('\\', '/'); viewIds.add(relativePath); } return StringUtil.toStringArray(viewIds); } private static FileFilter DIRECTORY_FILTER; private static void addFilePaths(File baseDir, List<String> fileAbsPaths, FilenameFilter filter) { // add the .xsp files to the List File[] files = baseDir.listFiles(filter); if( null != files ){ for (File file : files) { fileAbsPaths.add(file.getAbsolutePath()); } } // recurse through the folder if( null == DIRECTORY_FILTER ){ DIRECTORY_FILTER = new FileFilter(){ public boolean accept(File file) { return file.isDirectory(); } }; } File [] dirs = baseDir.listFiles(DIRECTORY_FILTER); if( null != dirs ){ for (File dir : dirs) { addFilePaths( dir, fileAbsPaths, filter ); } } } /** * Note, the parameter registry should be created using * {@link AbstractXspTest#getExtraConfig()} including * <pre>{"target.local.xspconfigs", "true"},</pre> * so that TestProject.createRegistry should include local xsp-configs. * @param reg * @return */ public static List<String> getCustomControlPageNames(FacesSharableRegistry reg) { List<String> ccPageNames = new ArrayList<String>(); for (FacesCompositeComponentDefinition def : reg.findCompositeLocalDefs()) { ccPageNames.add(def.getCompositeFile()); } return ccPageNames; } /** * This is only called during {@link #loadEmptyPage(AbstractXspTest, FacesContext)}. * @param context * @return */ public static UIViewRoot createViewRootObject(FacesContext context) { UIViewRoot result; ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if( null == classLoader ) classLoader = TestProject.class.getClassLoader(); // if the META-INF/extsn-faces-config.xml file is loaded Converter dateConverter = context.getApplication().createConverter(Date.class); boolean isXspDateTimeConverter; try{ String xspDateTimeConverterClassName = "com.ibm.xsp.convert.DateTimeConverter"; Class<?> xspDateTimeConverterClass = classLoader.loadClass(xspDateTimeConverterClassName); isXspDateTimeConverter = xspDateTimeConverterClass.isAssignableFrom(dateConverter.getClass()); } catch (ClassNotFoundException e) { isXspDateTimeConverter = false; } if( isXspDateTimeConverter ){ try{ String rootEx2ClassName = "com.ibm.xsp.component.UIViewRootEx2"; Class<?> rootEx2Class = classLoader.loadClass(rootEx2ClassName); result = (UIViewRoot) rootEx2Class.newInstance(); }catch(Exception e){ throw new RuntimeException(e); } }else{ result = new UIViewRoot(); } return result; } public static File detectDominoInstallLocation(AbstractXspTest test){ if( null != test.getTestLocalVars().get("dominoInstallLocation") ){ throw new RuntimeException("dominoInstallLocation already exists"); } String[] dominoSearchLocations; String[] defaultDominoSearchLocations = new String[]{ "c:\\Domino", "C:\\IBM\\Domino", "C:\\Program Files\\IBM\\Domino", "C:\\Program Files\\IBM\\Lotus\\Domino", "C:\\Program Files (x86)\\IBM\\Domino", "C:\\Program Files (x86)\\IBM\\Lotus\\Domino", "/opt/ibm/lotus", /*yeah, the folder name is lotus*/ "/opt/lotus", }; String[] configuredDominoSearchLocations = ConfigUtil.getDominoSearchLocations(test); if( null == configuredDominoSearchLocations ){ dominoSearchLocations = defaultDominoSearchLocations; }else{ String combineStrategy = ConfigUtil.getDominoSearchLocationsStrategy(test); if( "concat".equals(combineStrategy) ){ dominoSearchLocations = XspTestUtil.concat(configuredDominoSearchLocations, defaultDominoSearchLocations); }else{ // "override" dominoSearchLocations = configuredDominoSearchLocations; } } File dominoFolder = null; for (String path : dominoSearchLocations) { File possibleFolder = new File(path); if( possibleFolder.exists() ){ dominoFolder = possibleFolder; break; } } if( null == dominoFolder ){ String paths = StringUtil.concatStrings(dominoSearchLocations, /*separator*/',', /*trim*/false); throw new RuntimeException("Cannot find any of the suggested Domino install folders: "+paths); } test.getTestLocalVars().put("dominoInstallLocation", dominoFolder); return dominoFolder; } public static File getDominoInstallLocation(AbstractXspTest test){ File dominoFolder = (File) test.getTestLocalVars().get("dominoInstallLocation"); if( null == dominoFolder ){ throw new RuntimeException("TestUtil.detectDominoInstallLocation(AbstractXspTest) has not yet been called"); } return dominoFolder; } @SuppressWarnings("unchecked") public static List<TestControlInitializer> getControlInitializerList(AbstractXspTest test){ List<TestControlInitializer> list = (List<TestControlInitializer>) test.getTestLocalVars().get("controlInitializerList"); if( null != list ){ return list; } list = new ArrayList<TestControlInitializer>(); if( ! ConfigUtil.isPreventServiceControlInitializers(test) ){ ClassLoader classLoader = test.getClass() .getClassLoader(); List<TestControlInitializer> serviceList = loadService(TestControlInitializer.class, classLoader); for (TestControlInitializer initializer : serviceList) { list.add(initializer); } } if( test instanceof TestControlInitializer ){ list.add(0, (TestControlInitializer) test); } test.getTestLocalVars().put("controlInitializerList", list); return list; } @SuppressWarnings("unchecked") private static <T> List<T> loadService(Class<T> type, ClassLoader classLoader){ // Re-implementation of the Java6 method // java.util.ServiceLoader.load(Class) String serviceName = type.getName(); String path = "META-INF/services/"+serviceName; Enumeration<URL> fileUrls; try { fileUrls = classLoader.getResources(path); } catch (IOException e) { throw new IllegalArgumentException(e); } if( !fileUrls.hasMoreElements() ){ return Collections.emptyList(); } ArrayList<T> list = new ArrayList<T>(); for(Enumeration<URL> i = fileUrls; i.hasMoreElements(); ){ URL url = i.nextElement(); String fileContents = XspTestFileUtil.readFileContents(url); String[] classNames = StringUtil.splitString(fileContents, '\n', /*trim*/true); for (String className : classNames) { if( StringUtil.isEmpty(className) ){ continue; } try { Class<? extends T> classObj = (Class<? extends T>) classLoader.loadClass(className); T instance = classObj.newInstance(); list.add(instance); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } } return list; } }