All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.appng.testsupport.TestBase Maven / Gradle / Ivy

There is a newer version: 1.24.5
Show newest version
/*
 * Copyright 2011-2020 the original author or authors.
 *
 * 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.
 */
package org.appng.testsupport;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBException;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.appng.api.ActionProvider;
import org.appng.api.ApplicationConfigProvider;
import org.appng.api.BusinessException;
import org.appng.api.DataContainer;
import org.appng.api.DataProvider;
import org.appng.api.Environment;
import org.appng.api.FieldProcessor;
import org.appng.api.FileUpload.Unit;
import org.appng.api.InvalidConfigurationException;
import org.appng.api.ParameterSupport;
import org.appng.api.Path;
import org.appng.api.Platform;
import org.appng.api.ProcessingException;
import org.appng.api.Request;
import org.appng.api.Scope;
import org.appng.api.SiteProperties;
import org.appng.api.VHostMode;
import org.appng.api.model.Application;
import org.appng.api.model.ApplicationSubject;
import org.appng.api.model.FeatureProvider;
import org.appng.api.model.Group;
import org.appng.api.model.Permission;
import org.appng.api.model.Property;
import org.appng.api.model.Resource;
import org.appng.api.model.Resources;
import org.appng.api.model.Role;
import org.appng.api.model.SimpleProperty;
import org.appng.api.model.Site;
import org.appng.api.model.Subject;
import org.appng.api.search.Consumer;
import org.appng.api.search.DocumentEvent;
import org.appng.api.search.DocumentProducer;
import org.appng.api.support.ApplicationConfigProviderImpl;
import org.appng.api.support.ApplicationRequest;
import org.appng.api.support.ApplicationResourceHolder;
import org.appng.api.support.CallableAction;
import org.appng.api.support.CallableDataSource;
import org.appng.api.support.DollarParameterSupport;
import org.appng.api.support.DummyPermissionProcessor;
import org.appng.api.support.FieldProcessorImpl;
import org.appng.api.support.OptionImpl;
import org.appng.api.support.OptionsImpl;
import org.appng.api.support.PropertyHolder;
import org.appng.api.support.environment.DefaultEnvironment;
import org.appng.api.support.environment.EnvironmentKeys;
import org.appng.forms.FormUpload;
import org.appng.forms.impl.FormUploadBean;
import org.appng.forms.impl.RequestBean;
import org.appng.testsupport.persistence.ConnectionHelper;
import org.appng.testsupport.validation.WritingXmlValidator;
import org.appng.tools.image.ImageProcessor;
import org.appng.xml.BaseObject;
import org.appng.xml.MarshallService;
import org.appng.xml.application.ApplicationInfo;
import org.appng.xml.application.PermissionRef;
import org.appng.xml.platform.Action;
import org.appng.xml.platform.ActionRef;
import org.appng.xml.platform.Datasource;
import org.appng.xml.platform.DatasourceRef;
import org.appng.xml.platform.Event;
import org.appng.xml.platform.FieldDef;
import org.appng.xml.platform.MetaData;
import org.appng.xml.platform.Param;
import org.appng.xml.platform.Params;
import org.custommonkey.xmlunit.DifferenceListener;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * Base class for integration-testing an {@link Application}.
* * * Example Usage (w/o JPA): * *
 * @org.springframework.test.context.ContextConfiguration(initializers = MyTest.class)
 * public class MyTest extends TestBase {
 * 
 * 	public MyTest() {
 * 		super("myapplication", "application-home");
 * 	}
 * 
 * }
 * 
* * Example Usage (with JPA): * *
 * @org.springframework.test.context.ContextConfiguration(locations = {
 * 		TestBase.TESTCONTEXT_JPA }, initializers = MyTest.class)
 * public class MyTest extends TestBase {
 * 
 * 	public MyTest() {
 * 		super("myapplication", "application-home");
 * 		setEntityPackage("org.myapplication.domain");
 * 		setRepositoryBase("org.myapplication.repository");
 * 	}
 * 
 * }
 * 
* * Testing {@link ActionProvider}s and {@link DataProvider}s is this simple: * *
 * @org.junit.Test
 * public void testShowPersons() throws ProcessingException, IOException {
 * 	addParameter("sortPersons", "name:desc");
 * 	initParameters();
 * 	CallableDataSource datasource = getDataSource("persons").getCallableDataSource();
 * 	datasource.perform("personPage");
 * 	validate(datasource.getDatasource());
 * }
 * 
 * @org.junit.Test
 * public void testCreatePerson() throws ProcessingException, IOException {
 * 	CallableAction callableAction = getAction("personEvent", "create").withParam(FORM_ACTION, "create")
 * 			.getCallableAction(new Person("John", "Doe"));
 * 	FieldProcessor fieldProcessor = callableAction.perform();
 * 	validate(callableAction.getAction(), "-action");
 * 	validate(fieldProcessor.getMessages(), "-messages");
 * }
 * 
* * @author Matthias Müller * */ @ContextConfiguration(locations = { TestBase.BEANS_PATH, TestBase.TESTCONTEXT }) @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext public class TestBase implements ApplicationContextInitializer { private static final String SITE_PROP_PREFIX = "platform.site.localhost."; public static final String TESTCONTEXT = "classpath:org/appng/testsupport/application-testcontext.xml"; public static final String TESTCONTEXT_CORE = "classpath:org/appng/testsupport/application-testcontext-core.xml"; public static final String TESTCONTEXT_JPA = "classpath:org/appng/testsupport/application-testcontext-jpa.xml"; public static final String BEANS_PATH = "file:application-home/beans.xml"; protected static final String APPLICATION_HOME = "application-home"; protected static final String FORM_ACTION = "form_action"; private static final String SITE_MANAGER_PATH = "/manager"; private static final String SITE_SERVICE_PATH = "/service"; @Autowired protected ServletContext servletContext; protected HttpSession session; @Autowired protected MockHttpServletRequest servletRequest; protected MockHttpServletResponse servletResponse = new MockHttpServletResponse(); @Autowired protected ConfigurableApplicationContext context; @Autowired protected MessageSource messageSource; @Autowired protected ConversionService conversionService; @Autowired protected MarshallService marshallService; @Autowired @Qualifier("applicationMarshallService") private MarshallService applicationMarshallService; protected Environment environment; protected ApplicationRequest request; protected Application application; protected Site site; @Mock protected Subject subject; @Mock protected Path path; private String applicationName; private String applicationLocation; private String entityPackage; private String repositoryBase; private boolean useFullClassname = false; private Map parameters = new HashMap<>(); public TestBase() { this("application", APPLICATION_HOME); } public TestBase(String name) { this(name, APPLICATION_HOME); } protected void subjectWithRole(String roleName) { Group group = Mockito.mock(Group.class); Mockito.when(group.getRoles()).thenReturn(new HashSet<>()); for (Role role : application.getRoles()) { if (role.getName().equals(roleName)) { group.getRoles().add(role); } } List groups = new ArrayList<>(); groups.add(group); Mockito.when(subject.getGroups()).thenReturn(groups); } public TestBase(String applicationName, String applicationLocation) { Locale.setDefault(Locale.ENGLISH); this.applicationName = applicationName; this.applicationLocation = applicationLocation; } public void initialize(GenericApplicationContext applicationContext) { Properties properties = getProperties(); PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer(); placeholderConfigurer.setProperties(properties); applicationContext.addBeanFactoryPostProcessor(placeholderConfigurer); File dictFolder = new File(applicationLocation + "/dictionary").getAbsoluteFile(); final List baseNames = new ArrayList<>(); if (dictFolder.exists() && dictFolder.list() != null) { for (String file : dictFolder.list()) { if (FilenameUtils.getExtension(file).equalsIgnoreCase("properties")) { String name = FilenameUtils.getBaseName(file).replaceAll("_(.)*", ""); if (!baseNames.contains(name)) { baseNames.add(name); } } } try { URL dictUrl = dictFolder.toURI().toURL(); URLClassLoader classLoader = new URLClassLoader(new URL[] { dictUrl }, getClass().getClassLoader()); applicationContext.setClassLoader(classLoader); } catch (MalformedURLException e) { // impossible! } } applicationContext.addBeanFactoryPostProcessor(pp -> { baseNames.add("messages-core"); ResourceBundleMessageSource bean = pp.getBean(ResourceBundleMessageSource.class); bean.setBasenames(baseNames.toArray(new String[baseNames.size()])); }); application = mockApplication(applicationContext); mockSite(applicationContext); } protected void mockSite(GenericApplicationContext applicationContext) { if (null == site) { site = Mockito.mock(Site.class); } Mockito.when(site.getName()).thenReturn("localhost"); Mockito.when(site.getDomain()).thenReturn("localhost"); Mockito.when(site.getHost()).thenReturn("localhost"); Mockito.when(site.getApplication(applicationName)).thenReturn(application); Mockito.when(site.getSiteClassLoader()).thenReturn(new URLClassLoader(new URL[0])); List siteProperties = getSiteProperties(SITE_PROP_PREFIX); Mockito.when(site.getProperties()).thenReturn(new PropertyHolder(SITE_PROP_PREFIX, siteProperties)); if (null != applicationContext) { applicationContext.addBeanFactoryPostProcessor(pp -> pp.registerSingleton("site", site)); } } @SuppressWarnings("unchecked") protected Application mockApplication(GenericApplicationContext applicationContext) { if (null == application) { application = Mockito.mock(Application.class); } Mockito.when(application.getName()).thenReturn(applicationName); Mockito.when(application.isFileBased()).thenReturn(true); try { Resources resources = getApplicationResources(MarshallService.getApplicationMarshallService()); Mockito.when(application.getResources()).thenReturn(resources); ApplicationInfo applicationInfo = resources.getApplicationInfo(); org.appng.api.model.Properties properties = extractProperties(getProperties(), applicationInfo); Mockito.when(application.getProperties()).thenReturn(properties); } catch (JAXBException e) { throw new RuntimeException("error reading resources", e); } Mockito.when(application.getBean(Mockito.any(Class.class))) .thenAnswer(i -> applicationContext.getBean(i.getArgumentAt(0, Class.class))); Mockito.when(application.getBean(Mockito.any(String.class))) .thenAnswer(i -> applicationContext.getBean(i.getArgumentAt(0, String.class))); Mockito.when(application.getBean(Mockito.any(String.class), Mockito.any(Class.class))).thenAnswer( i -> applicationContext.getBean(i.getArgumentAt(0, String.class), i.getArgumentAt(1, Class.class))); applicationContext.addBeanFactoryPostProcessor(pp -> pp.registerSingleton("application", application)); return application; } protected Resources getApplicationResources(MarshallService applicationMarshallService) { try { return new ApplicationResourceHolder(application, applicationMarshallService, new File(applicationLocation), new File("target/temp")); } catch (InvalidConfigurationException e) { throw new RuntimeException("error reading resources", e); } } protected Resources mockResources() { return Mockito.mock(Resources.class); } /** * Returns the {@link Properties} used by * {@link ApplicationContextInitializer#initialize(ConfigurableApplicationContext)} and also for the * {@link Application}'s properties. Override in subclasses to add custom values. * * @return the properties to use * @see Application#getProperties() * @see #initialize(GenericApplicationContext) */ protected Properties getProperties() { Properties properties = new Properties(); properties.put("entityPackage", entityPackage); properties.put("hsqlPort", ConnectionHelper.getHsqlPort()); properties.put("repositoryBase", repositoryBase); return properties; } /** * Adds a parameter to the {@link org.appng.api.Request} used in the testcase.
* After all parameters have been added, {@link #initParameters()} (or {@link #initParameters(boolean)}) has to be * called.
* Not to confiuse with {@link DataSourceCall#withParam(String, String)} and * {@link ActionCall#withParam(String, String)}! * * @param name * the name of the parameter * @param value * the value of the parameter */ protected void addParameter(String name, String value) { parameters.put(name, value); } protected FormUpload getFormUpload(String resourceName) throws URISyntaxException { URL resource = getClass().getClassLoader().getResource(resourceName); File file = new File(resource.toURI()); String extension = FilenameUtils.getExtension(resourceName); long maxSize = 10 * Unit.MB.getFactor(); return new FormUploadBean(file, file.getName(), extension, Arrays.asList(extension), maxSize); } @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); initEnvironment(); application = new SimpleApplication(applicationName, context, getApplicationSubjects()); initRequest(); ((SimpleApplication) application).init(getProperties(), request.getApplicationConfig().getApplicationInfo()); } protected List getApplicationSubjects() { return new ArrayList<>(); } protected void initRequest() throws InvalidConfigurationException, JAXBException { Resources applicationResources = getApplicationResources(applicationMarshallService); ApplicationConfigProvider applicationConfigProvider = new ApplicationConfigProviderImpl(marshallService, applicationName, applicationResources, false); request = (ApplicationRequest) context.getBean(Request.class); request.setPermissionProcessor(new DummyPermissionProcessor(subject, site, application)); request.setApplicationConfig(applicationConfigProvider); } /** * Initializes the {@link org.appng.api.Request} for the testcase. Before, some paramters can be added using * {@link #addParameter(String, String)} */ protected void initParameters() { initParameters(false); } protected void initParameters(boolean isPost) { servletRequest.setParameters(parameters); init(isPost); } protected void init(boolean isPost) { if (isPost) { servletRequest.setMethod("POST"); } RequestBean requestBean = new RequestBean(); requestBean.process(servletRequest); request.setWrappedRequest(requestBean); } protected void initEnvironment() { ConcurrentHashMap platformEnv = new ConcurrentHashMap<>(); List platformProperties = getPlatformProperties("platform."); platformEnv.put(Platform.Environment.PLATFORM_CONFIG, new PropertyHolder("platform.", platformProperties)); mockSite(null); Map sites = new HashMap<>(); sites.put(site.getHost(), site); platformEnv.put(Platform.Environment.SITES, sites); this.session = new MockHttpSession(servletContext); servletContext.setAttribute(Scope.PLATFORM.name(), platformEnv); environment = context.getBean("environment", Environment.class); if (!((DefaultEnvironment) environment).isInitialized()) { environment.init(servletContext, session, servletRequest, servletResponse, site.getHost()); } environment.setAttribute(Scope.REQUEST, EnvironmentKeys.PATH_INFO, path); Mockito.when(path.getServicePath()).thenReturn(SITE_SERVICE_PATH); Mockito.when(path.getGuiPath()).thenReturn(SITE_MANAGER_PATH); } protected List getSiteProperties(String prefix) { List siteProperties = new ArrayList<>(); siteProperties.add(new SimpleProperty(prefix + SiteProperties.SERVICE_PATH, SITE_SERVICE_PATH)); siteProperties.add(new SimpleProperty(prefix + SiteProperties.MANAGER_PATH, SITE_MANAGER_PATH)); siteProperties.add(new SimpleProperty(prefix + SiteProperties.DEFAULT_PAGE_SIZE, "25")); return siteProperties; } protected List getPlatformProperties(String prefix) { List platformProperties = new ArrayList<>(); platformProperties.add(new SimpleProperty(prefix + Platform.Property.VHOST_MODE, VHostMode.NAME_BASED.name())); platformProperties.add(new SimpleProperty(prefix + Platform.Property.LOCALE, "en")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.TIME_ZONE, "Europe/Berlin")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.PLATFORM_ROOT_PATH, "target/ROOT")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.CACHE_FOLDER, "cache")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.APPLICATION_CACHE_FOLDER, "application")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.PLATFORM_CACHE_FOLDER, "platform")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.UPLOAD_DIR, "/target/uploads")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.MAX_UPLOAD_SIZE, "10485760")); platformProperties.add(new SimpleProperty(prefix + Platform.Property.XSS_PROTECT, "false")); return platformProperties; } public void validate(BaseObject object) throws IOException { String controlFile = getControlFileName(null); WritingXmlValidator.validateXml(object, controlFile); } public void validate(BaseObject object, DifferenceListener differenceListener) throws IOException { String controlFile = getControlFileName(null); WritingXmlValidator.validateXml(object, controlFile, differenceListener); } public void validate(BaseObject object, String suffix, DifferenceListener differenceListener) throws IOException { String controlFile = getControlFileName(suffix); WritingXmlValidator.validateXml(object, controlFile, differenceListener); } public void validate(BaseObject object, String suffix) throws IOException { String controlFile = getControlFileName(suffix); WritingXmlValidator.validateXml(object, controlFile); } private String getControlFileName(String suffix) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); StackTraceElement stackTraceElement = stackTrace[3]; String className = stackTraceElement.getClassName(); if (!useFullClassname) { className = className.substring(className.lastIndexOf('.') + 1); } String controlFile = "xml" + File.separator + className + "-" + stackTraceElement.getMethodName() + (suffix == null ? "" : suffix) + ".xml"; return controlFile; } class CallableTestAction extends CallableAction { private Object form; CallableTestAction(Site site, Application application, ApplicationRequest applicationRequest, ActionRef actionRef, Object form) throws ProcessingException { super(site, application, applicationRequest, actionRef); this.form = form; } @Override protected Object getBindObject(FieldProcessor fieldProcessor) throws BusinessException { if (null != form) { BeanWrapper original = new BeanWrapperImpl(form); BeanWrapper copy = new BeanWrapperImpl(form.getClass()); for (FieldDef fieldDef : fieldProcessor.getMetaData().getFields()) { copy.setPropertyValue(fieldDef.getBinding(), original.getPropertyValue(fieldDef.getBinding())); } return copy.getWrappedInstance(); } return null; } private Action initialize() throws ProcessingException { retrieveData(false); return getAction(); } } protected String getEntityPackage() { return entityPackage; } protected void setEntityPackage(String entityPackage) { this.entityPackage = entityPackage; } protected String getRepositoryBase() { return repositoryBase; } protected void setRepositoryBase(String repositoryBase) { this.repositoryBase = repositoryBase; } protected boolean isUseFullClassname() { return useFullClassname; } protected void setUseFullClassname(boolean useFullClassname) { this.useFullClassname = useFullClassname; } class ParametrizedCall { private Map configParams = new HashMap<>(); private Params params; ParametrizedCall(Params params) { this.params = params; } Params getParams() { for (String key : configParams.keySet()) { Param param = new Param(); param.setName(key); param.setValue(configParams.get(key)); params.getParam().add(param); } return params; } ParameterSupport getParameterSupport() { return new DollarParameterSupport(configParams); } ParametrizedCall clearParams() { configParams.clear(); getParams().getParam().clear(); return this; } ParametrizedCall withParam(String name, String value) { configParams.put(name, value); return this; } } /** * Returns a {@link DataSourceCall} that wraps a {@link DatasourceRef}, using the given id for a {@link Datasource} * * @param id * the id of the {@link Datasource} * @return the {@link DataSourceCall} */ protected DataSourceCall getDataSource(String id) { return new DataSourceCall(id); } /** * Returns an {@link ActionCall} that wraps an {@link ActionRef}, using the given id for an {@link Action}. * * @param eventId * the id of the {@link Event} * @param id * the id of the {@link Action} * @return the {@link ActionCall} */ protected ActionCall getAction(String eventId, String id) { return new ActionCall(eventId, id); } org.appng.api.model.Properties extractProperties(Properties overrides, ApplicationInfo applicationInfo) { Set props = new HashSet<>(); for (org.appng.xml.application.Property prop : applicationInfo.getProperties().getProperty()) { String propName = prop.getId(); String value = overrides.containsKey(propName) ? overrides.getProperty(propName) : prop.getValue(); SimpleProperty property; if (Boolean.TRUE.equals(prop.isClob())) { property = new SimpleProperty(propName, null); property.setClob(value); } else { property = new SimpleProperty(propName, value); } property.setDescription(prop.getDescription()); props.add(property); } return new PropertyHolder(StringUtils.EMPTY, props); } /** * Returns a {@link HandlerMethodArgumentResolver} that can resolve a(n) *
    *
  • {@link Environment} *
  • {@link Site} *
  • {@link Application} *
* Useful when testing a {@link Controller}/ {@link RestController} with {@link MockMvc}: * *
	 * MockMvc mockMvc = MockMvcBuilders.standaloneSetup(context.getBean(MyRestController.class))
	 * 		.setCustomArgumentResolvers(getHandlerMethodArgumentResolver()).build();
	 * 
* * @return the resolver */ public HandlerMethodArgumentResolver getHandlerMethodArgumentResolver() { return new HandlerMethodArgumentResolver() { public boolean supportsParameter(MethodParameter parameter) { return isSite(parameter) || isEnvironment(parameter) || isApplication(parameter); } public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { return isSite(parameter) ? site : (isEnvironment(parameter) ? environment : (isApplication(parameter) ? application : null)); } private boolean isParameterType(MethodParameter parameter, Class type) { return parameter.getParameterType().equals(type); } private boolean isEnvironment(MethodParameter parameter) { return isParameterType(parameter, Environment.class); } protected boolean isSite(MethodParameter parameter) { return isParameterType(parameter, Site.class); } private boolean isApplication(MethodParameter parameter) { return isParameterType(parameter, Application.class); } }; } /** * A wrapper for a {@link DatasourceRef}, allowing to add {@link Param}eters and to retrieve the actual * {@link CallableDataSource}. */ protected class DataSourceCall extends DatasourceRef { private ParametrizedCall parametrizedCall; DataSourceCall(String id) { setId(id); setParams(new Params()); this.parametrizedCall = new ParametrizedCall(super.getParams()); } @Override public Params getParams() { return parametrizedCall.getParams(); } ParameterSupport getParameterSupport() { return parametrizedCall.getParameterSupport(); } public DataSourceCall clearParams() { parametrizedCall.clearParams(); return this; } /** * Adds a {@link Param} to the wrapped {@link DatasourceRef}. * * @param name * the name of the {@link Param} * @param value * the value * @return */ public DataSourceCall withParam(String name, String value) { parametrizedCall.withParam(name, value); return this; } /** * Returns the {@link CallableDataSource}. * * @return the {@link CallableDataSource} * @throws ProcessingException * if an error occurs while assembling the CallableDataSource */ public CallableDataSource getCallableDataSource() throws ProcessingException { return new CallableDataSource(site, application, request, getParameterSupport(), this); } } /** * A wrapper for an {@link ActionRef}, allowing to add {@link Param}eters and to retrieve the actual * {@link CallableAction}. */ protected class ActionCall extends ActionRef { private ParametrizedCall parametrizedCall; ActionCall(String eventId, String id) { setEventId(eventId); setId(id); setParams(new Params()); this.parametrizedCall = new ParametrizedCall(super.getParams()); } @Override public Params getParams() { return parametrizedCall.getParams(); } ParameterSupport getParameterSupport() { return parametrizedCall.getParameterSupport(); } public ActionCall clearParams() { parametrizedCall.clearParams(); return this; } /** * Adds a {@link Param} to the wrapped {@link ActionRef}. * * @param name * the name of the {@link Param} * @param value * the value * @return */ public ActionCall withParam(String name, String value) { parametrizedCall.withParam(name, value); return this; } /** * Returns the {@link CallableAction}. * * @param form * an instance of the bind-object used by the {@link Action}. The type must be compatible with * {@link MetaData#getBindClass()} of the {@link Datasource} that is used by the {@link Action}. * @return the {@link CallableAction} * @throws ProcessingException * if an error occurs while assembling the CallableAction */ public CallableAction getCallableAction(Object form) throws ProcessingException { return new CallableTestAction(site, application, request, this, form); } /** * Returns the {@link Action} in it's initial state, meaning the action is initialized with the original data * coming from {@link DataProvider}, but not performed. * * @return the {@link Action} * @throws ProcessingException * if an error occurs while assembling the Action */ public Action initialize() throws ProcessingException { return new CallableTestAction(site, application, request, this, null).initialize(); } /** * Returns the initial form for the action, i.e. of the underlying {@link Datasource}, if any. This is done by * directly calling * {@link DataProvider#getData(Site, Application, Environment, org.appng.api.Options, Request, FieldProcessor)} * and then returning the result of {@link DataContainer#getItem()}. * * @return the initial form, may be {@code null} * @throws ProcessingException * if an error occurs while retrieving the data */ @SuppressWarnings("unchecked") public T getForm() throws ProcessingException { CallableTestAction callableTestAction = new CallableTestAction(site, application, request, this, null); DatasourceRef datasourceRef = callableTestAction.getAction().getDatasource(); if (null != datasourceRef) { DataSourceCall dataSourceCall = new DataSourceCall(datasourceRef.getId()); if (null != datasourceRef.getParams()) { Map parameters = getParameterSupport().getParameters(); datasourceRef.getParams().getParam() .forEach(p -> dataSourceCall.withParam(p.getName(), parameters.get(p.getName()))); } Datasource datasource = dataSourceCall.getCallableDataSource().getDatasource(); OptionsImpl options = new OptionsImpl(); datasource.getBean().getOptions().forEach(o -> { OptionImpl opt = new OptionImpl(o.getName()); o.getOtherAttributes().entrySet() .forEach(e -> opt.addAttribute(e.getKey().getLocalPart(), e.getValue())); options.addOption(opt); }); MetaData metaData = datasource.getConfig().getMetaData(); FieldProcessorImpl fp = new FieldProcessorImpl(id, metaData); fp.addLinkPanels(datasource.getConfig().getLinkpanel()); DataProvider dataProvider = application.getBean(datasource.getBean().getId(), DataProvider.class); DataContainer dataContainer = dataProvider.getData(site, application, environment, options, request, fp); return (T) dataContainer.getItem(); } return null; } } protected class SimpleApplication implements Application { private String name; private ConfigurableApplicationContext context; private Map permissionMap = new HashMap<>(); private Set roleSet; private org.appng.api.model.Properties properties; private List applicationSubjects; private SimpleFeatureProvider featureProvider; private ApplicationInfo applicationInfo; protected SimpleApplication(String name, ConfigurableApplicationContext context) { this(name, context, new ArrayList<>()); } protected SimpleApplication(String name, ConfigurableApplicationContext context, List applicationSubjects) { this.name = name; this.context = context; this.applicationSubjects = applicationSubjects; } protected void init(Properties overrides, ApplicationInfo applicationInfo) { this.applicationInfo = applicationInfo; for (org.appng.xml.application.Permission p : applicationInfo.getPermissions().getPermission()) { Permission simplePermission = new SimplePermission(p); permissionMap.put(p.getId(), simplePermission); } roleSet = new HashSet<>(); int roleId = 1; for (org.appng.xml.application.Role r : applicationInfo.getRoles().getRole()) { SimpleRole role = new SimpleRole(r, roleId++); List permission = r.getPermission(); for (PermissionRef permissionRef : permission) { Permission e = permissionMap.get(permissionRef.getId()); role.getPermissions().add(e); } roleSet.add(role); } properties = extractProperties(overrides, applicationInfo); featureProvider = new SimpleFeatureProvider(properties); } public String getName() { return name; } public String getDisplayName() { return applicationInfo.getDisplayName(); } public String getPackageVersion() { return applicationInfo.getVersion(); } public String getTimestamp() { return applicationInfo.getTimestamp(); } public String getLongDescription() { return applicationInfo.getLongDescription(); } public String getAppNGVersion() { return applicationInfo.getAppngVersion(); } public boolean isInstalled() { return true; } public boolean isSnapshot() { return getPackageVersion().endsWith("-SNAPSHOT"); } public String getDescription() { return applicationInfo.getDescription(); } public Integer getId() { return null; } public Date getVersion() { return null; } public Set getPermissions() { return new HashSet<>(permissionMap.values()); } public Set getRoles() { return roleSet; } public Resources getResources() { return request.getApplicationConfig().getResources(); } public Set getResourceSet() { return getResources().getResources(); } public org.appng.api.model.Properties getProperties() { return properties; } public T getBean(String name, Class clazz) { return context.getBean(name, clazz); } public String[] getBeanNames(Class clazz) { return context.getBeanNamesForType(clazz); } public T getBean(Class clazz) { return context.getBean(clazz); } public Object getBean(String beanName) { return context.getBean(beanName); } public boolean containsBean(String beanName) { return context.containsBean(name); } public boolean isFileBased() { return true; } public boolean isPrivileged() { return false; } @Deprecated public boolean isCoreApplication() { return isPrivileged(); } public boolean isHidden() { return false; } public String getMessage(Locale locale, String key, Object... args) { return messageSource.getMessage(key, args, locale); } public String getSessionParamKey(Site site) { return site.getName() + "." + getName(); } public Map getSessionParams(Site site, Environment environment) { String sessionParamKey = getSessionParamKey(site); Map sessionsParams = environment.getAttribute(Scope.SESSION, sessionParamKey); if (null == sessionsParams) { sessionsParams = new HashMap<>(); environment.setAttribute(Scope.SESSION, sessionParamKey, sessionsParams); } return sessionsParams; } public SimpleFeatureProvider getFeatureProvider() { return featureProvider; } public List getApplicationSubjects() { return applicationSubjects; } } protected class SimpleFeatureProvider implements FeatureProvider { private int documentCount = 0; private org.appng.api.model.Properties properties; SimpleFeatureProvider(org.appng.api.model.Properties properties) { this.properties = properties; } public Consumer getIndexer() { if (properties.getString("featureIndexing", "false").equalsIgnoreCase("true")) { return new Consumer() { @Override public void put(DocumentProducer element) throws InterruptedException { super.put(element); documentCount++; } @Override public boolean put(DocumentProducer element, long timeoutMillis) throws InterruptedException { documentCount++; return super.put(element, timeoutMillis); } @Override public void putWithTimeout(DocumentProducer element, long timeoutMillis) throws InterruptedException, TimeoutException { super.putWithTimeout(element, timeoutMillis); documentCount++; } }; } return null; } public Integer getDocumentCount() { return documentCount; } public ImageProcessor getImageProcessor(File sourceFile, String targetFile) { if (properties.getString("featureImageProcessing", "false").equalsIgnoreCase("true")) { return new ImageProcessor(sourceFile, new File(getImageCache(), targetFile)); } return null; } public File getImageCache() { if (properties.getString("featureImageProcessing", "false").equalsIgnoreCase("true")) { return new File("target/imageCache"); } return null; } } class SimpleRole implements Role { private org.appng.xml.application.Role role; private Set permissions = new HashSet<>(); private Integer id; public SimpleRole(org.appng.xml.application.Role role, Integer id) { this.role = role; this.id = id; } public String getName() { return role.getName(); } public String getDescription() { return role.getDescription(); } public Integer getId() { return id; } public Application getApplication() { return application; } public Set getPermissions() { return permissions; } } class SimplePermission implements Permission { private org.appng.xml.application.Permission permission; SimplePermission(org.appng.xml.application.Permission permission) { this.permission = permission; } public String getName() { return permission.getId(); } public String getDescription() { return permission.getValue(); } public Integer getId() { return null; } public Application getApplication() { return application; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy