diff --git a/lightadmin-core/src/main/java/org/lightadmin/api/config/LightAdmin.java b/lightadmin-core/src/main/java/org/lightadmin/api/config/LightAdmin.java index 61c2e721..81f7192a 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/api/config/LightAdmin.java +++ b/lightadmin-core/src/main/java/org/lightadmin/api/config/LightAdmin.java @@ -73,7 +73,11 @@ public LightAdmin fileStreaming(boolean fileStreaming) { } public LightAdmin demoMode() { - servletContext.setInitParameter(LIGHT_ADMINISTRATION_DEMO_MODE, Boolean.toString(true)); + return demoMode(true); + } + + public LightAdmin demoMode(boolean demoMode) { + servletContext.setInitParameter(LIGHT_ADMINISTRATION_DEMO_MODE, Boolean.toString(demoMode)); return this; } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/Editors.java b/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/Editors.java index a0238d90..2bea35b6 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/Editors.java +++ b/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/Editors.java @@ -15,18 +15,22 @@ */ package org.lightadmin.api.config.utils; -import org.lightadmin.core.view.editor.EnumFieldEditControl; -import org.lightadmin.core.view.editor.JspFragmentFieldControl; - -import java.util.List; - import static com.google.common.collect.Lists.newArrayList; import static java.util.Arrays.asList; import static org.lightadmin.api.config.utils.EnumElement.element; +import java.util.List; + +import org.lightadmin.core.view.editor.EnumFieldEditControl; +import org.lightadmin.core.view.editor.JspFragmentFieldControl; + @SuppressWarnings("unused") public abstract class Editors { + public static JspFragmentFieldControl collection() { + return new JspFragmentFieldControl("/views/editors/collection-field-edit-control.jsp"); + } + public static JspFragmentFieldControl textArea() { return new JspFragmentFieldControl("/views/editors/textarea-field-edit-control.jsp"); } diff --git a/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/EnumElement.java b/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/EnumElement.java index 935f2560..d1b18b95 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/EnumElement.java +++ b/lightadmin-core/src/main/java/org/lightadmin/api/config/utils/EnumElement.java @@ -16,6 +16,8 @@ package org.lightadmin.api.config.utils; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; public class EnumElement implements Serializable { @@ -48,5 +50,14 @@ public static EnumElement element(long value, String label) { public static EnumElement element(String value, String label) { return new EnumElement(value, label); } + + public static EnumElement[] enumElements(Class> clazz){ + List els = new ArrayList(); + for(Enum el : clazz.getEnumConstants()){ + els.add(EnumElement.element(el.name(), el.name())); + } + return els.toArray(new EnumElement[]{}); + } + } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminWebApplicationInitializer.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminWebApplicationInitializer.java index 1e097e23..a47a3dd2 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminWebApplicationInitializer.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminWebApplicationInitializer.java @@ -15,7 +15,36 @@ */ package org.lightadmin.core.config; +import static org.apache.commons.io.FileUtils.getFile; +import static org.apache.commons.lang3.BooleanUtils.toBoolean; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMINISTRATION_BASE_PACKAGE; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMINISTRATION_BASE_URL; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMINISTRATION_FILE_STORAGE_PATH; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMINISTRATION_SECURITY; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_FRAGMENT_SERVLET_URL; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_FRAGMENT_LOCATION; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_CLASSPATH_LOCATION; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_SERVLET_NAME; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_DEFAULT_LOGO_LOCATION; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_DISPATCHER_NAME; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_DISPATCHER_REDIRECTOR_NAME; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_LOGO_RESOURCE_SERVLET_NAME; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_LOGO_SERVLET_URL; +import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; + +import java.io.File; +import java.util.regex.Pattern; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.http.HttpServletRequest; + import net.sf.ehcache.constructs.web.filter.GzipFilter; + import org.lightadmin.core.config.bootstrap.LightAdminBeanDefinitionRegistryPostProcessor; import org.lightadmin.core.config.context.LightAdminContextConfiguration; import org.lightadmin.core.config.context.LightAdminSecurityConfiguration; @@ -36,19 +65,6 @@ import org.springframework.web.servlet.FrameworkServlet; import org.springframework.web.servlet.ResourceServlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.http.HttpServletRequest; -import java.io.File; -import java.util.regex.Pattern; - -import static org.apache.commons.io.FileUtils.getFile; -import static org.apache.commons.lang3.BooleanUtils.toBoolean; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.lightadmin.core.util.LightAdminConfigurationUtils.*; -import static org.springframework.core.Ordered.LOWEST_PRECEDENCE; - @SuppressWarnings("unused") @Order(LOWEST_PRECEDENCE) public class LightAdminWebApplicationInitializer implements WebApplicationInitializer { @@ -142,7 +158,6 @@ private ResourceServlet logoResourceServlet(ServletContext servletContext) { if (webResource.exists()) { return concreteResourceServlet(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); } - return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_DEFAULT_LOGO_LOCATION)); } @@ -283,6 +298,7 @@ private ResourceLoader defaultResourceLoader() { private ResourceServlet concreteResourceServlet(final String location) { return new ResourceServlet() { + private static final long serialVersionUID = 4602656496188884537L; { setApplyLastModified(true); setContentType("image/png"); diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/LightAdminBeanDefinitionRegistryPostProcessor.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/LightAdminBeanDefinitionRegistryPostProcessor.java index 904e84ca..6ecacf89 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/LightAdminBeanDefinitionRegistryPostProcessor.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/LightAdminBeanDefinitionRegistryPostProcessor.java @@ -15,6 +15,7 @@ */ package org.lightadmin.core.config.bootstrap; +import org.apache.tika.metadata.Geographic; import org.lightadmin.core.config.bootstrap.parsing.validation.CompositeConfigurationUnitsValidator; import org.lightadmin.core.config.bootstrap.scanning.AdministrationClassScanner; import org.lightadmin.core.config.bootstrap.scanning.ClassScanner; @@ -33,6 +34,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.core.io.ResourceLoader; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; +import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.SharedEntityManagerCreator; @@ -44,6 +46,7 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.metamodel.EntityType; import javax.servlet.ServletContext; + import java.util.Set; import static com.google.common.collect.Sets.newHashSet; @@ -89,10 +92,13 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) t registry.registerBeanDefinition(JPA_MAPPPING_CONTEXT_BEAN, mappingContext(entityManager)); registry.registerBeanDefinition(CONFIGURATION_UNITS_VALIDATOR_BEAN, configurationUnitsValidator(resourceLoader)); - + + Repositories repositories = new Repositories(rootContext); for (Class managedEntityType : managedEntities(entityManager)) { - Class repoInterface = createDynamicRepositoryClass(managedEntityType, entityManager); - registry.registerBeanDefinition(beanName(repoInterface), repositoryFactory(repoInterface, entityManager)); + if(!repositories.hasRepositoryFor(managedEntityType)){ + Class repoInterface = createDynamicRepositoryClass(managedEntityType, entityManager); + registry.registerBeanDefinition(beanName(repoInterface), repositoryFactory(repoInterface, entityManager)); + } } registerRepositoryEventListeners(configurationUnits, registry); diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestMvcConfiguration.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestMvcConfiguration.java index e643bb56..05a38543 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestMvcConfiguration.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestMvcConfiguration.java @@ -15,9 +15,13 @@ */ package org.lightadmin.core.config.context; -import com.fasterxml.jackson.databind.ObjectMapper; +import static com.google.common.collect.Lists.newLinkedList; +import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; +import static org.springframework.util.ClassUtils.isAssignableValue; + +import java.util.List; + import org.lightadmin.core.config.LightAdminConfiguration; -import org.lightadmin.core.config.bootstrap.RepositoriesFactoryBean; import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; import org.lightadmin.core.persistence.repository.event.FileManipulationRepositoryEventListener; import org.lightadmin.core.persistence.repository.invoker.DynamicRepositoryInvokerFactory; @@ -25,14 +29,16 @@ import org.lightadmin.core.storage.FileResourceStorage; import org.lightadmin.core.web.json.DomainTypeToJsonMetadataConverter; import org.lightadmin.core.web.json.LightAdminJacksonModule; -import org.lightadmin.core.web.support.*; -import org.springframework.beans.BeanInstantiationException; +import org.lightadmin.core.web.support.ConfigurationHandlerMethodArgumentResolver; +import org.lightadmin.core.web.support.DomainEntityLinks; +import org.lightadmin.core.web.support.DynamicPersistentEntityResourceAssemblerArgumentResolver; +import org.lightadmin.core.web.support.DynamicPersistentEntityResourceProcessor; +import org.lightadmin.core.web.support.DynamicRepositoryEntityLinks; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.data.repository.support.Repositories; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; import org.springframework.data.rest.core.invoke.RepositoryInvokerFactory; @@ -44,11 +50,7 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; -import java.util.List; - -import static com.google.common.collect.Lists.newLinkedList; -import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; -import static org.springframework.util.ClassUtils.isAssignableValue; +import com.fasterxml.jackson.databind.ObjectMapper; @Configuration @ComponentScan(basePackages = {"org.lightadmin.core.web"}, @@ -78,15 +80,6 @@ public DomainTypeToJsonMetadataConverter domainTypeToJsonMetadataConverter() { return new DomainTypeToJsonMetadataConverter(globalAdministrationConfiguration(), entityLinks()); } - @Bean - public Repositories repositories() { - try { - return new RepositoriesFactoryBean(beanFactory).getObject(); - } catch (Exception e) { - throw new BeanInstantiationException(Repositories.class, "Repositories bean instantiation problem!", e); - } - } - @Bean public DomainObjectMerger domainObjectMerger() throws Exception { return new DynamicDomainObjectMerger(repositories(), defaultConversionService(), globalAdministrationConfiguration()); diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/processor/EmptyConfigurationUnitPostProcessor.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/processor/EmptyConfigurationUnitPostProcessor.java index 58954466..c7706308 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/processor/EmptyConfigurationUnitPostProcessor.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/processor/EmptyConfigurationUnitPostProcessor.java @@ -17,6 +17,7 @@ import org.lightadmin.api.config.builder.FieldSetConfigurationUnitBuilder; import org.lightadmin.api.config.unit.FieldSetConfigurationUnit; +import org.lightadmin.api.config.utils.EnumElement; import org.lightadmin.core.config.domain.common.GenericFieldSetConfigurationUnitBuilder; import org.lightadmin.core.config.domain.unit.ConfigurationUnit; import org.lightadmin.core.config.domain.unit.ConfigurationUnits; @@ -69,6 +70,9 @@ private FieldSetConfigurationUnit fieldSetUnitWithPersistentFields(final Class property, FieldSetConfigurationUnitBuilder fieldSetConfigurationUnitBuilder) { if (isSupportedAttributeType(PersistentPropertyType.forPersistentProperty(property))) { fieldSetConfigurationUnitBuilder.field(property.getName()).caption(capitalize(property.getName())); + if(PersistentPropertyType.ENUM.equals(PersistentPropertyType.forPersistentProperty(property))){ + fieldSetConfigurationUnitBuilder.enumeration(EnumElement.enumElements((Class>) property.getActualType())); + } } } @@ -96,6 +100,7 @@ public void doWithAssociation(Association> assoc return persistentProperties; } + private static class PersistentPropertyComparator implements Comparator { @Override public int compare(final PersistentProperty persistentProperty1, final PersistentProperty persistentProperty2) { @@ -106,6 +111,7 @@ public int compare(final PersistentProperty persistentProperty1, final Persisten return 1; } return persistentProperty1.getName().compareTo(persistentProperty2.getName()); + } private boolean isPrimaryKey(PersistentProperty persistentProperty) { diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/metamodel/PersistentPropertyType.java b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/metamodel/PersistentPropertyType.java index 779b90fc..6fd813b8 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/metamodel/PersistentPropertyType.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/metamodel/PersistentPropertyType.java @@ -50,6 +50,7 @@ public enum PersistentPropertyType { ENUM, EMBEDDED, MAP, + COLLECTION, UNKNOWN; public static PersistentPropertyType forPersistentProperty(PersistentProperty persistentProperty) { @@ -74,6 +75,10 @@ public static PersistentPropertyType forPersistentProperty(PersistentProperty pe return ENUM; } + if (persistentProperty.isCollectionLike()) { + return PersistentPropertyType.COLLECTION; + } + if (forType(attrType) == STRING && persistentProperty.isAnnotationPresent(FileReference.class)) { return PersistentPropertyType.FILE; } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/view/tags/form/EditControlDispatcherTag.java b/lightadmin-core/src/main/java/org/lightadmin/core/view/tags/form/EditControlDispatcherTag.java index 557699e7..1e48c8a1 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/view/tags/form/EditControlDispatcherTag.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/view/tags/form/EditControlDispatcherTag.java @@ -42,6 +42,7 @@ public class EditControlDispatcherTag extends SimpleTagSupport { private JspFragment n2oneEditControl; private JspFragment n2manyEditControl; private JspFragment mapEditControl; + private JspFragment collectionEditControl; @Override public void doTag() throws JspException, IOException { @@ -71,6 +72,9 @@ private void doWithStandardControl() throws JspException, IOException { case MAP: worker = mapEditControl; break; + case COLLECTION: + worker = collectionEditControl; + break; case BOOL: worker = booleanEditControl; break; @@ -142,7 +146,11 @@ public void setMapEditControl(JspFragment control) { this.mapEditControl = control; } - public void setFileEditControl(final JspFragment fileEditControl) { + public void setCollectionEditControl(JspFragment collectionEditControl) { + this.collectionEditControl = collectionEditControl; + } + + public void setFileEditControl(final JspFragment fileEditControl) { this.fileEditControl = fileEditControl; } diff --git a/lightadmin-core/src/main/resources/META-INF/resources/scripts/controllers/lightadmin-formview-controller.js b/lightadmin-core/src/main/resources/META-INF/resources/scripts/controllers/lightadmin-formview-controller.js index 4ac04087..19a3acdf 100644 --- a/lightadmin-core/src/main/resources/META-INF/resources/scripts/controllers/lightadmin-formview-controller.js +++ b/lightadmin-core/src/main/resources/META-INF/resources/scripts/controllers/lightadmin-formview-controller.js @@ -161,16 +161,32 @@ function LoadDomainEntityAction(resourceName) { var property = fields[fieldIdx]; var propertyName = property['name']; var propertyType = property['type']; - - var editor = form.find('[name="' + propertyName + '"]'); - if (editor.length == 0) { - continue; - } - + var propertyValue = domainEntity.getPropertyValue(property, 'formView'); if (propertyValue == null) { continue; } + + var editors = form.find('[name="' + propertyName + '[]"]'); + if (editors.length > 0) { + var lastEditor = $(editors[0]); + for (var propertyValueIdx in propertyValue) { + var ePropertyValue = propertyValue[propertyValueIdx]; + if(ePropertyValue != null){ + lastEditor.val(ePropertyValue); + nextEditor = $(""); + lastEditor.after(nextEditor); + lastEditor.after("
"); + lastEditor = nextEditor; + } + } + continue; + } + + var editor = form.find('[name="' + propertyName + '"]'); + if (editor.length == 0) { + continue; + } switch (propertyType) { case 'ASSOC': diff --git a/lightadmin-core/src/main/resources/META-INF/resources/scripts/lightadmin-serializer.js b/lightadmin-core/src/main/resources/META-INF/resources/scripts/lightadmin-serializer.js index 191b9f70..1fb5761d 100644 --- a/lightadmin-core/src/main/resources/META-INF/resources/scripts/lightadmin-serializer.js +++ b/lightadmin-core/src/main/resources/META-INF/resources/scripts/lightadmin-serializer.js @@ -35,33 +35,37 @@ var json = {}; $.each(this.serializeArray(), function () { var attrVal = this.value || ''; - - var property = ConfigurationMetadataService.getProperty(resourceName, this.name, 'formView'); - + var propertyName = this.name.replace("[]", ""); + var property = ConfigurationMetadataService.getProperty(resourceName, propertyName, 'formView'); if (property == null) { - if ( isPartialPropertyField(this.name) && attrVal.length != 0) { - var main_property_name = this.name.substr(0, this.name.indexOf("_time")); + if ( isPartialPropertyField(propertyName) && attrVal.length != 0) { + var main_property_name = propertyName.substr(0, propertyName.indexOf("_time")); if (json[main_property_name] != null && json[main_property_name].length != 0) { json[main_property_name] = json[main_property_name] + 'T' + attrVal; } } return; } - var propertyType = property['type']; - - if (propertyType.indexOf('ASSOC') == 0) { + if (propertyType.indexOf('COLLECTION') == 0) { + if (!json[propertyName]) { + json[propertyName] = []; + } + if(attrVal != ''){ + json[propertyName].push(attrVal); + } + }else if (propertyType.indexOf('ASSOC') == 0) { var href = resolveObjectHref(attrVal, property); if (propertyType == 'ASSOC_MULTI') { - if (!json[this.name]) { - json[this.name] = []; + if (!json[propertyName]) { + json[propertyName] = []; } - json[this.name].push(href); + json[propertyName].push(href); } else { - json[this.name] = href; + json[propertyName] = href; } } else { - json[this.name] = attrVal; + json[propertyName] = attrVal; } }); diff --git a/lightadmin-core/src/main/resources/META-INF/resources/views/editors/collection-field-edit-control.jsp b/lightadmin-core/src/main/resources/META-INF/resources/views/editors/collection-field-edit-control.jsp new file mode 100644 index 00000000..e41f530d --- /dev/null +++ b/lightadmin-core/src/main/resources/META-INF/resources/views/editors/collection-field-edit-control.jsp @@ -0,0 +1,21 @@ +<%@ page import="org.lightadmin.core.persistence.metamodel.PersistentPropertyType" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="light" uri="http://www.lightadmin.org/tags" %> + + + + +
+Add Element + + \ No newline at end of file