From f7322d8c065e8ebcaa0316da760df8e3abc98a9e Mon Sep 17 00:00:00 2001 From: grahman Date: Tue, 20 Feb 2018 17:55:34 -0500 Subject: [PATCH 01/18] Bug that configuration types were not serialized properly by Jackson and hence was giving parse error in JavaScript, is fixed. --- .../unit/DomainConfigurationUnitType.java | 113 +++++++++--------- 1 file changed, 59 insertions(+), 54 deletions(-) diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java index 33ddd47a..abce5332 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java @@ -1,55 +1,60 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.domain.unit; - -import static java.lang.String.format; - -public enum DomainConfigurationUnitType { - - SCREEN_CONTEXT("screenContext"), - CONFIGURATION("configuration"), - LIST_VIEW("listView"), - SHOW_VIEW("showView"), - FORM_VIEW("formView"), - QUICK_VIEW("quickView"), - SCOPES("scopes"), - FILTERS("filters"), - SIDEBARS("sidebars"); - - private final String name; - - private DomainConfigurationUnitType(final String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public static DomainConfigurationUnitType forName(String name) { - for (DomainConfigurationUnitType domainConfigurationUnitType : values()) { - if (domainConfigurationUnitType.getName().equals(name)) { - return domainConfigurationUnitType; - } - } - throw new IllegalArgumentException(format("Configuration Unit for name %s not defined!", name)); - } - - @Override - public String toString() { - return getName(); - } +/* + * Copyright 2012-2014 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.lightadmin.core.config.domain.unit; + +import static java.lang.String.format; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum DomainConfigurationUnitType { + + SCREEN_CONTEXT("screenContext"), + CONFIGURATION("configuration"), + LIST_VIEW("listView"), + SHOW_VIEW("showView"), + FORM_VIEW("formView"), + QUICK_VIEW("quickView"), + SCOPES("scopes"), + FILTERS("filters"), + SIDEBARS("sidebars"); + + private final String name; + + @JsonCreator + private DomainConfigurationUnitType(final String name) { + this.name = name; + } + + @JsonValue + public String getName() { + return name; + } + + public static DomainConfigurationUnitType forName(String name) { + for (DomainConfigurationUnitType domainConfigurationUnitType : values()) { + if (domainConfigurationUnitType.getName().equals(name)) { + return domainConfigurationUnitType; + } + } + throw new IllegalArgumentException(format("Configuration Unit for name %s not defined!", name)); + } + + @Override + public String toString() { + return getName(); + } } \ No newline at end of file From 102058442dc022d76dfb67c5503d828791068bef Mon Sep 17 00:00:00 2001 From: grahman Date: Tue, 20 Feb 2018 17:58:24 -0500 Subject: [PATCH 02/18] Bug that User (principal) name is not shown in the UI, is fixed. --- .../views/sections/top-navigation-section.jsp | 137 +++++++++--------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/lightadmin-core/src/main/resources/META-INF/resources/views/sections/top-navigation-section.jsp b/lightadmin-core/src/main/resources/META-INF/resources/views/sections/top-navigation-section.jsp index adbdd219..bb1f04e1 100644 --- a/lightadmin-core/src/main/resources/META-INF/resources/views/sections/top-navigation-section.jsp +++ b/lightadmin-core/src/main/resources/META-INF/resources/views/sections/top-navigation-section.jsp @@ -1,69 +1,70 @@ -<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> -<%@ taglib prefix="light" uri="http://www.lightadmin.org/tags" %> -<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> -<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> - - - - - -
-
-
- - - -
- - - Hello, - - - - - - - ! -
-
- -
-
- -
- -
- - -
- -
- - Fork me on GitHub -
- -
-
-
+<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> + +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="light" uri="http://www.lightadmin.org/tags" %> +<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> +<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> + + + + + +
+
+
+ + + + +
+ + + Hello, + + + + + + + ! +
+
+ +
+
+ +
+ +
+ + +
+ +
+ + Fork me on GitHub +
+ +
+
+
\ No newline at end of file From 6f07b93b690ce30da8964769e9bc9ce309994a4d Mon Sep 17 00:00:00 2001 From: grahman Date: Wed, 21 Feb 2018 13:21:11 -0500 Subject: [PATCH 03/18] Spring platform upgraded to 2.0.8 version. --- lightadmin-core/pom.xml | 2 +- lightadmin-sandbox/pom.xml | 4 +- lightadmin-tests/pom.xml | 470 ++++++++++++++++++------------------- pom.xml | 138 +++++------ 4 files changed, 307 insertions(+), 307 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 9aa8a28c..8ec4bdaf 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.2.0.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 02d28756..a073f093 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.0.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT lightadmin-sandbox - 1.2.0.BUILD-SNAPSHOT + 1.3.0.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 79c30063..2246eaf6 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -1,235 +1,235 @@ - - - - 4.0.0 - - - org.lightadmin - lightadmin-parent - 1.2.0.BUILD-SNAPSHOT - - - lightadmin-tests - 1.2.0.BUILD-SNAPSHOT - - LightAdmin Selenium - - - 8080 - - 2.45.0 - 1.4.01 - - - - - org.lightadmin - lightadmin-sandbox - ${project.version} - war - - - org.lightadmin - lightadmin-sandbox - ${project.version} - classes - - - - org.seleniumhq.selenium - selenium-java - ${selenium-java.version} - - - - xml-apis - xml-apis - ${xml-apis.version} - - - - com.google.guava - guava - - - - org.slf4j - slf4j-api - - - ch.qos.logback - logback-classic - runtime - - - - org.springframework - spring-core - - - commons-logging - commons-logging - - - - - org.springframework - spring-context - - - - javax.servlet.jsp - javax.servlet.jsp-api - - - - org.springframework - spring-test - - - junit - junit - - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.12 - - - integration-test - integration-test - - integration-test - - - - **/*.class - - true - - - - verify - verify - - verify - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.12 - - true - - - - - - - - - test-mode - - - mode - test - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - dev-mode - - - mode - dev - - - - - - org.codehaus.cargo - cargo-maven2-plugin - 1.2.4 - - - start-cargo - pre-integration-test - - start - - - - stop-cargo - post-integration-test - - stop - - - - - - jetty8x - - org.eclipse.jetty - jetty-distribution - 8.1.8.v20121106 - - - - - ${project.groupId} - lightadmin-sandbox - war - - lightadmin-sandbox - - - - - - ${container.port} - - - - ${basedir}/src/test/jetty8x/jetty-logging.xml - etc - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - - + + + + 4.0.0 + + + org.lightadmin + lightadmin-parent + 1.3.0.BUILD-SNAPSHOT + + + lightadmin-tests + 1.3.0.BUILD-SNAPSHOT + + LightAdmin Selenium + + + 8080 + + 2.45.0 + 1.4.01 + + + + + org.lightadmin + lightadmin-sandbox + ${project.version} + war + + + org.lightadmin + lightadmin-sandbox + ${project.version} + classes + + + + org.seleniumhq.selenium + selenium-java + ${selenium-java.version} + + + + xml-apis + xml-apis + ${xml-apis.version} + + + + com.google.guava + guava + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + runtime + + + + org.springframework + spring-core + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + + + + javax.servlet.jsp + javax.servlet.jsp-api + + + + org.springframework + spring-test + + + junit + junit + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.12 + + + integration-test + integration-test + + integration-test + + + + **/*.class + + true + + + + verify + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + true + + + + + + + + + test-mode + + + mode + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + dev-mode + + + mode + dev + + + + + + org.codehaus.cargo + cargo-maven2-plugin + 1.2.4 + + + start-cargo + pre-integration-test + + start + + + + stop-cargo + post-integration-test + + stop + + + + + + jetty8x + + org.eclipse.jetty + jetty-distribution + 8.1.8.v20121106 + + + + + ${project.groupId} + lightadmin-sandbox + war + + lightadmin-sandbox + + + + + + ${container.port} + + + + ${basedir}/src/test/jetty8x/jetty-logging.xml + etc + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + diff --git a/pom.xml b/pom.xml index 0f43fefa..8bca7111 100644 --- a/pom.xml +++ b/pom.xml @@ -1,70 +1,70 @@ - - - 4.0.0 - org.lightadmin - lightadmin-parent - 1.2.0.BUILD-SNAPSHOT - pom - - LightAdmin Dev Kit - - - UTF-8 - UTF-8 - - 1.7 - 1.7 - - 1.1.2.RELEASE - 1.2 - - 1.0.0.BUILD-SNAPSHOT - - - - - - io.spring.platform - platform-bom - ${spring.platform.version} - pom - import - - - - org.lightadmin - lightadmin - ${project.version} - - - org.lightadmin - light-logging-configurer - ${light-logging-configurer.version} - - - - org.glassfish.web - jstl-impl - ${jstl.version} - - - javax.servlet - servlet-api - - - javax.servlet.jsp - jsp-api - - - - - - - - lightadmin-core - lightadmin-sandbox - lightadmin-tests - - + + + 4.0.0 + org.lightadmin + lightadmin-parent + 1.3.0.BUILD-SNAPSHOT + pom + + LightAdmin Dev Kit + + + UTF-8 + UTF-8 + + 1.7 + 1.7 + + 2.0.8.RELEASE + 1.2 + + 1.0.0.BUILD-SNAPSHOT + + + + + + io.spring.platform + platform-bom + ${spring.platform.version} + pom + import + + + + org.lightadmin + lightadmin + ${project.version} + + + org.lightadmin + light-logging-configurer + ${light-logging-configurer.version} + + + + org.glassfish.web + jstl-impl + ${jstl.version} + + + javax.servlet + servlet-api + + + javax.servlet.jsp + jsp-api + + + + + + + + lightadmin-core + lightadmin-sandbox + lightadmin-tests + + \ No newline at end of file From 1d235f5bbf1e4bb28271dd84d4b83835b169b33e Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 12:36:41 -0500 Subject: [PATCH 04/18] Revert "Spring platform upgraded to 2.0.8 version." This reverts commit 6f07b93b690ce30da8964769e9bc9ce309994a4d. --- lightadmin-core/pom.xml | 2 +- lightadmin-sandbox/pom.xml | 4 +- lightadmin-tests/pom.xml | 470 ++++++++++++++++++------------------- pom.xml | 138 +++++------ 4 files changed, 307 insertions(+), 307 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 8ec4bdaf..9aa8a28c 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.3.0.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index a073f093..02d28756 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.3.0.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT lightadmin-sandbox - 1.3.0.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 2246eaf6..79c30063 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -1,235 +1,235 @@ - - - - 4.0.0 - - - org.lightadmin - lightadmin-parent - 1.3.0.BUILD-SNAPSHOT - - - lightadmin-tests - 1.3.0.BUILD-SNAPSHOT - - LightAdmin Selenium - - - 8080 - - 2.45.0 - 1.4.01 - - - - - org.lightadmin - lightadmin-sandbox - ${project.version} - war - - - org.lightadmin - lightadmin-sandbox - ${project.version} - classes - - - - org.seleniumhq.selenium - selenium-java - ${selenium-java.version} - - - - xml-apis - xml-apis - ${xml-apis.version} - - - - com.google.guava - guava - - - - org.slf4j - slf4j-api - - - ch.qos.logback - logback-classic - runtime - - - - org.springframework - spring-core - - - commons-logging - commons-logging - - - - - org.springframework - spring-context - - - - javax.servlet.jsp - javax.servlet.jsp-api - - - - org.springframework - spring-test - - - junit - junit - - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.12 - - - integration-test - integration-test - - integration-test - - - - **/*.class - - true - - - - verify - verify - - verify - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.12 - - true - - - - - - - - - test-mode - - - mode - test - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - dev-mode - - - mode - dev - - - - - - org.codehaus.cargo - cargo-maven2-plugin - 1.2.4 - - - start-cargo - pre-integration-test - - start - - - - stop-cargo - post-integration-test - - stop - - - - - - jetty8x - - org.eclipse.jetty - jetty-distribution - 8.1.8.v20121106 - - - - - ${project.groupId} - lightadmin-sandbox - war - - lightadmin-sandbox - - - - - - ${container.port} - - - - ${basedir}/src/test/jetty8x/jetty-logging.xml - etc - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - - + + + + 4.0.0 + + + org.lightadmin + lightadmin-parent + 1.2.0.BUILD-SNAPSHOT + + + lightadmin-tests + 1.2.0.BUILD-SNAPSHOT + + LightAdmin Selenium + + + 8080 + + 2.45.0 + 1.4.01 + + + + + org.lightadmin + lightadmin-sandbox + ${project.version} + war + + + org.lightadmin + lightadmin-sandbox + ${project.version} + classes + + + + org.seleniumhq.selenium + selenium-java + ${selenium-java.version} + + + + xml-apis + xml-apis + ${xml-apis.version} + + + + com.google.guava + guava + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + runtime + + + + org.springframework + spring-core + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + + + + javax.servlet.jsp + javax.servlet.jsp-api + + + + org.springframework + spring-test + + + junit + junit + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.12 + + + integration-test + integration-test + + integration-test + + + + **/*.class + + true + + + + verify + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + true + + + + + + + + + test-mode + + + mode + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + dev-mode + + + mode + dev + + + + + + org.codehaus.cargo + cargo-maven2-plugin + 1.2.4 + + + start-cargo + pre-integration-test + + start + + + + stop-cargo + post-integration-test + + stop + + + + + + jetty8x + + org.eclipse.jetty + jetty-distribution + 8.1.8.v20121106 + + + + + ${project.groupId} + lightadmin-sandbox + war + + lightadmin-sandbox + + + + + + ${container.port} + + + + ${basedir}/src/test/jetty8x/jetty-logging.xml + etc + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + diff --git a/pom.xml b/pom.xml index 8bca7111..0f43fefa 100644 --- a/pom.xml +++ b/pom.xml @@ -1,70 +1,70 @@ - - - 4.0.0 - org.lightadmin - lightadmin-parent - 1.3.0.BUILD-SNAPSHOT - pom - - LightAdmin Dev Kit - - - UTF-8 - UTF-8 - - 1.7 - 1.7 - - 2.0.8.RELEASE - 1.2 - - 1.0.0.BUILD-SNAPSHOT - - - - - - io.spring.platform - platform-bom - ${spring.platform.version} - pom - import - - - - org.lightadmin - lightadmin - ${project.version} - - - org.lightadmin - light-logging-configurer - ${light-logging-configurer.version} - - - - org.glassfish.web - jstl-impl - ${jstl.version} - - - javax.servlet - servlet-api - - - javax.servlet.jsp - jsp-api - - - - - - - - lightadmin-core - lightadmin-sandbox - lightadmin-tests - - + + + 4.0.0 + org.lightadmin + lightadmin-parent + 1.2.0.BUILD-SNAPSHOT + pom + + LightAdmin Dev Kit + + + UTF-8 + UTF-8 + + 1.7 + 1.7 + + 1.1.2.RELEASE + 1.2 + + 1.0.0.BUILD-SNAPSHOT + + + + + + io.spring.platform + platform-bom + ${spring.platform.version} + pom + import + + + + org.lightadmin + lightadmin + ${project.version} + + + org.lightadmin + light-logging-configurer + ${light-logging-configurer.version} + + + + org.glassfish.web + jstl-impl + ${jstl.version} + + + javax.servlet + servlet-api + + + javax.servlet.jsp + jsp-api + + + + + + + + lightadmin-core + lightadmin-sandbox + lightadmin-tests + + \ No newline at end of file From 4c56a306335b795161c1c9657a9e350c49deaf5e Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 12:50:30 -0500 Subject: [PATCH 05/18] Spring Platform upgradation to version 2.0.8 has been started. --- lightadmin-core/pom.xml | 5 +- .../core/config/LightAdminConfiguration.java | 90 ++-- .../StandardLightAdminConfiguration.java | 281 ++++++----- ...JpaMetamodelMappingContextFactoryBean.java | 142 +++--- ...htAdminRepositoryRestMvcConfiguration.java | 368 +++++++------- .../LightAdminSecurityConfiguration.java | 424 ++++++++-------- .../invoker/DynamicRepositoryInvoker.java | 68 +-- .../DynamicRepositoryInvokerFactory.java | 78 +-- .../DynamicRepositoryInvokerWrapper.java | 245 +++++---- .../web/RepositoryFilePropertyController.java | 380 +++++++------- ...amicPersistentEntityResourceAssembler.java | 171 +++---- lightadmin-sandbox/pom.xml | 4 +- lightadmin-tests/pom.xml | 470 +++++++++--------- pom.xml | 138 ++--- 14 files changed, 1433 insertions(+), 1431 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 9aa8a28c..db2297a6 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -7,8 +7,7 @@ org.lightadmin lightadmin jar - - 1.2.0.BUILD-SNAPSHOT + 1.3.1.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner @@ -95,7 +94,7 @@ 1.7 1.7 - 1.1.2.RELEASE + 2.0.8.RELEASE 4.0 4.2 diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminConfiguration.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminConfiguration.java index 3f7e6d28..1d76a3a9 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminConfiguration.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/LightAdminConfiguration.java @@ -1,45 +1,47 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config; - -import java.io.File; -import java.net.URI; - -public interface LightAdminConfiguration { - - String getBasePackage(); - - String getApplicationBaseUrl(); - - String getApplicationUrl(String path); - - URI getApplicationRestBaseUrl(); - - boolean isSecurityEnabled(); - - boolean isDemoMode(); - - String getSecurityLogoutUrl(); - - String getBackToSiteUrl(); - - String getHelpUrl(); - - File getFileStorageDirectory(); - - boolean isFileStreamingEnabled(); - +/* + * Copyright 2012-2014 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.lightadmin.core.config; + +import java.io.File; +import java.net.URI; + +public interface LightAdminConfiguration { + + String getBasePackage(); + + String getApplicationBaseUrl(); + + String getApplicationUrl(String path); + + URI getApplicationRestBaseUrl(); + + String getApplicationRestBasePath(); + + boolean isSecurityEnabled(); + + boolean isDemoMode(); + + String getSecurityLogoutUrl(); + + String getBackToSiteUrl(); + + String getHelpUrl(); + + File getFileStorageDirectory(); + + boolean isFileStreamingEnabled(); + } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/StandardLightAdminConfiguration.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/StandardLightAdminConfiguration.java index f00624a3..6359824a 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/StandardLightAdminConfiguration.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/StandardLightAdminConfiguration.java @@ -1,139 +1,144 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config; - -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.web.util.UriComponentsBuilder; - -import javax.servlet.ServletContext; -import java.io.File; -import java.net.URI; - -import static org.apache.commons.io.FileUtils.getFile; -import static org.apache.commons.lang3.StringUtils.defaultIfBlank; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.lightadmin.core.util.LightAdminConfigurationUtils.*; - -public class StandardLightAdminConfiguration implements LightAdminConfiguration { - - private final String applicationBaseUrl; - private final String applicationBaseNoEndSeparator; - private final boolean securityEnabled; - private final String securityLogoutUrl; - private final String backToSiteUrl; - private final String helpUrl; - private final File fileStorageDirectory; - private final boolean fileStreaming; - private final String basePackage; - private final boolean demoMode; - - public StandardLightAdminConfiguration(ServletContext servletContext) { - this.basePackage = servletContext.getInitParameter(LIGHT_ADMINISTRATION_BASE_PACKAGE); - - this.applicationBaseUrl = servletContext.getInitParameter(LIGHT_ADMINISTRATION_BASE_URL); - this.applicationBaseNoEndSeparator = urlWithoutEndSeparator(this.applicationBaseUrl); - this.backToSiteUrl = backToSiteUrl(servletContext); - this.helpUrl = helpUrl(servletContext); - - this.fileStorageDirectory = fileStorageDirectory(servletContext); - this.fileStreaming = BooleanUtils.toBoolean(servletContext.getInitParameter(LIGHT_ADMINISTRATION_FILE_STREAMING)); - - this.demoMode = BooleanUtils.toBoolean(servletContext.getInitParameter(LIGHT_ADMINISTRATION_DEMO_MODE)); - - this.securityEnabled = BooleanUtils.toBoolean(servletContext.getInitParameter(LIGHT_ADMINISTRATION_SECURITY)); - if (securityEnabled) { - this.securityLogoutUrl = servletContext.getContextPath() + this.applicationBaseNoEndSeparator + LIGHT_ADMIN_SECURITY_LOGOUT_URL_DEFAULT; - } else { - this.securityLogoutUrl = servletContext.getContextPath() + defaultIfBlank(servletContext.getInitParameter(LIGHT_ADMINISTRATION_SECURITY_LOGOUT_URL), "#"); - } - } - - @Override - public URI getApplicationRestBaseUrl() { - return UriComponentsBuilder.fromUriString(LIGHT_ADMIN_REST_URL_DEFAULT).build().toUri(); - } - - @Override - public String getBasePackage() { - return this.basePackage; - } - - @Override - public File getFileStorageDirectory() { - return fileStorageDirectory; - } - - @Override - public boolean isFileStreamingEnabled() { - return fileStreaming; - } - - @Override - public String getBackToSiteUrl() { - return backToSiteUrl; - } - - @Override - public String getHelpUrl() { - return helpUrl; - } - - @Override - public String getApplicationBaseUrl() { - return applicationBaseUrl; - } - - @Override - public String getApplicationUrl(String path) { - return applicationBaseNoEndSeparator + path; - } - - @Override - public boolean isSecurityEnabled() { - return securityEnabled; - } - - public boolean isDemoMode() { - return demoMode; - } - - @Override - public String getSecurityLogoutUrl() { - return securityLogoutUrl; - } - - private File fileStorageDirectory(ServletContext servletContext) { - final String fileStoragePath = servletContext.getInitParameter(LIGHT_ADMINISTRATION_FILE_STORAGE_PATH); - - return isBlank(fileStoragePath) ? null : getFile(fileStoragePath); - } - - private String backToSiteUrl(ServletContext servletContext) { - final String backToSiteUrl = servletContext.getInitParameter(LIGHT_ADMINISTRATION_BACK_TO_SITE_URL); - - return isBlank(backToSiteUrl) ? LIGHT_ADMINISTRATION_BACK_TO_SITE_DEFAULT_URL : backToSiteUrl; - } - - private String helpUrl(ServletContext servletContext) { - final String helpUrl = servletContext.getInitParameter(LIGHT_ADMINISTRATION_HELP_URL); - - return isBlank(helpUrl) ? LIGHT_ADMINISTRATION_HELP_DEFAULT_URL : helpUrl; - } - - private String urlWithoutEndSeparator(String url) { - return url.endsWith("/") ? url.substring(0, url.length() - 1) : url; - } +/* + * Copyright 2012-2014 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.lightadmin.core.config; + +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.servlet.ServletContext; +import java.io.File; +import java.net.URI; + +import static org.apache.commons.io.FileUtils.getFile; +import static org.apache.commons.lang3.StringUtils.defaultIfBlank; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.*; + +public class StandardLightAdminConfiguration implements LightAdminConfiguration { + + private final String applicationBaseUrl; + private final String applicationBaseNoEndSeparator; + private final boolean securityEnabled; + private final String securityLogoutUrl; + private final String backToSiteUrl; + private final String helpUrl; + private final File fileStorageDirectory; + private final boolean fileStreaming; + private final String basePackage; + private final boolean demoMode; + + public StandardLightAdminConfiguration(ServletContext servletContext) { + this.basePackage = servletContext.getInitParameter(LIGHT_ADMINISTRATION_BASE_PACKAGE); + + this.applicationBaseUrl = servletContext.getInitParameter(LIGHT_ADMINISTRATION_BASE_URL); + this.applicationBaseNoEndSeparator = urlWithoutEndSeparator(this.applicationBaseUrl); + this.backToSiteUrl = backToSiteUrl(servletContext); + this.helpUrl = helpUrl(servletContext); + + this.fileStorageDirectory = fileStorageDirectory(servletContext); + this.fileStreaming = BooleanUtils.toBoolean(servletContext.getInitParameter(LIGHT_ADMINISTRATION_FILE_STREAMING)); + + this.demoMode = BooleanUtils.toBoolean(servletContext.getInitParameter(LIGHT_ADMINISTRATION_DEMO_MODE)); + + this.securityEnabled = BooleanUtils.toBoolean(servletContext.getInitParameter(LIGHT_ADMINISTRATION_SECURITY)); + if (securityEnabled) { + this.securityLogoutUrl = servletContext.getContextPath() + this.applicationBaseNoEndSeparator + LIGHT_ADMIN_SECURITY_LOGOUT_URL_DEFAULT; + } else { + this.securityLogoutUrl = servletContext.getContextPath() + defaultIfBlank(servletContext.getInitParameter(LIGHT_ADMINISTRATION_SECURITY_LOGOUT_URL), "#"); + } + } + + @Override + public URI getApplicationRestBaseUrl() { + return UriComponentsBuilder.fromUriString(LIGHT_ADMIN_REST_URL_DEFAULT).build().toUri(); + } + + @Override + public String getApplicationRestBasePath() { + return LIGHT_ADMIN_REST_URL_DEFAULT; + } + + @Override + public String getBasePackage() { + return this.basePackage; + } + + @Override + public File getFileStorageDirectory() { + return fileStorageDirectory; + } + + @Override + public boolean isFileStreamingEnabled() { + return fileStreaming; + } + + @Override + public String getBackToSiteUrl() { + return backToSiteUrl; + } + + @Override + public String getHelpUrl() { + return helpUrl; + } + + @Override + public String getApplicationBaseUrl() { + return applicationBaseUrl; + } + + @Override + public String getApplicationUrl(String path) { + return applicationBaseNoEndSeparator + path; + } + + @Override + public boolean isSecurityEnabled() { + return securityEnabled; + } + + public boolean isDemoMode() { + return demoMode; + } + + @Override + public String getSecurityLogoutUrl() { + return securityLogoutUrl; + } + + private File fileStorageDirectory(ServletContext servletContext) { + final String fileStoragePath = servletContext.getInitParameter(LIGHT_ADMINISTRATION_FILE_STORAGE_PATH); + + return isBlank(fileStoragePath) ? null : getFile(fileStoragePath); + } + + private String backToSiteUrl(ServletContext servletContext) { + final String backToSiteUrl = servletContext.getInitParameter(LIGHT_ADMINISTRATION_BACK_TO_SITE_URL); + + return isBlank(backToSiteUrl) ? LIGHT_ADMINISTRATION_BACK_TO_SITE_DEFAULT_URL : backToSiteUrl; + } + + private String helpUrl(ServletContext servletContext) { + final String helpUrl = servletContext.getInitParameter(LIGHT_ADMINISTRATION_HELP_URL); + + return isBlank(helpUrl) ? LIGHT_ADMINISTRATION_HELP_DEFAULT_URL : helpUrl; + } + + private String urlWithoutEndSeparator(String url) { + return url.endsWith("/") ? url.substring(0, url.length() - 1) : url; + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/JpaMetamodelMappingContextFactoryBean.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/JpaMetamodelMappingContextFactoryBean.java index 82365dd7..eef96bf3 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/JpaMetamodelMappingContextFactoryBean.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/bootstrap/JpaMetamodelMappingContextFactoryBean.java @@ -1,71 +1,73 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.bootstrap; - -import org.springframework.beans.factory.config.AbstractFactoryBean; -import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; -import org.springframework.util.Assert; - -import javax.persistence.EntityManager; -import javax.persistence.metamodel.ManagedType; -import javax.persistence.metamodel.Metamodel; -import java.util.HashSet; -import java.util.Set; - -public class JpaMetamodelMappingContextFactoryBean extends AbstractFactoryBean { - - private EntityManager entityManager; - - @Override - public Class getObjectType() { - return JpaMetamodelMappingContext.class; - } - - @Override - protected JpaMetamodelMappingContext createInstance() throws Exception { - Metamodel metamodel = entityManager.getMetamodel(); - - Set> managedTypes = metamodel.getManagedTypes(); - Set> entitySources = new HashSet>(managedTypes.size()); - - for (ManagedType type : managedTypes) { - - Class javaType = type.getJavaType(); - - if (javaType != null) { - entitySources.add(javaType); - } - } - - JpaMetamodelMappingContext context = new JpaMetamodelMappingContext(metamodel); - context.setInitialEntitySet(entitySources); - context.initialize(); - - return context; - } - - @Override - public void afterPropertiesSet() throws Exception { - Assert.notNull(entityManager, "EntityManager must not be null!"); - super.afterPropertiesSet(); - } - - @SuppressWarnings("unused") - public void setEntityManager(EntityManager entityManager) { - Assert.notNull(entityManager, "EntityManager must not be null!"); - this.entityManager = entityManager; - } +/* + * Copyright 2012-2014 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.lightadmin.core.config.bootstrap; + +import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; +import org.springframework.util.Assert; + +import javax.persistence.EntityManager; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Metamodel; +import java.util.HashSet; +import java.util.Set; + +public class JpaMetamodelMappingContextFactoryBean extends AbstractFactoryBean { + + private EntityManager entityManager; + + @Override + public Class getObjectType() { + return JpaMetamodelMappingContext.class; + } + + @Override + protected JpaMetamodelMappingContext createInstance() throws Exception { + Metamodel metamodel = entityManager.getMetamodel(); + + Set> managedTypes = metamodel.getManagedTypes(); + Set> entitySources = new HashSet>(managedTypes.size()); + + for (ManagedType type : managedTypes) { + + Class javaType = type.getJavaType(); + + if (javaType != null) { + entitySources.add(javaType); + } + } + + Set metamodels = new HashSet<>(); + metamodels.add(metamodel); + JpaMetamodelMappingContext context = new JpaMetamodelMappingContext(metamodels); + context.setInitialEntitySet(entitySources); + context.initialize(); + + return context; + } + + @Override + public void afterPropertiesSet() throws Exception { + Assert.notNull(entityManager, "EntityManager must not be null!"); + super.afterPropertiesSet(); + } + + @SuppressWarnings("unused") + public void setEntityManager(EntityManager entityManager) { + Assert.notNull(entityManager, "EntityManager must not be null!"); + this.entityManager = entityManager; + } } \ No newline at end of file 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..58aabc00 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 @@ -1,185 +1,185 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.context; - -import com.fasterxml.jackson.databind.ObjectMapper; -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; -import org.lightadmin.core.persistence.support.DynamicDomainObjectMerger; -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.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; -import org.springframework.data.rest.core.support.DomainObjectMerger; -import org.springframework.data.rest.webmvc.RepositoryRestController; -import org.springframework.data.rest.webmvc.config.PersistentEntityResourceAssemblerArgumentResolver; -import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; -import org.springframework.validation.Validator; -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; - -@Configuration -@ComponentScan(basePackages = {"org.lightadmin.core.web"}, - includeFilters = @ComponentScan.Filter(RepositoryRestController.class), useDefaultFilters = false) -public class LightAdminRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration { - - @Autowired - private ListableBeanFactory beanFactory; - - @Bean - public DomainEntityLinks domainEntityLinks() { - return new DomainEntityLinks(globalAdministrationConfiguration(), backendIdConverterRegistry(), lightAdminConfiguration()); - } - - @Bean - public DynamicRepositoryEntityLinks dynamicRepositoryEntityLinks() { - return DynamicRepositoryEntityLinks.wrap(super.entityLinks()); - } - - @Bean - public DynamicPersistentEntityResourceProcessor dynamicPersistentEntityResourceProcessor() { - return new DynamicPersistentEntityResourceProcessor(globalAdministrationConfiguration(), fileResourceStorage(), dynamicRepositoryEntityLinks(), domainEntityLinks(), resourceMappings()); - } - - @Bean - 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()); - } - - @Bean - public RepositoryInvokerFactory repositoryInvokerFactory() { - RepositoryInvokerFactory repositoryInvokerFactory = super.repositoryInvokerFactory(); - - return new DynamicRepositoryInvokerFactory(repositories(), repositoryInvokerFactory); - } - - @Bean - public ConfigurationHandlerMethodArgumentResolver configurationHandlerMethodArgumentResolver() { - return new ConfigurationHandlerMethodArgumentResolver(globalAdministrationConfiguration(), resourceMetadataHandlerMethodArgumentResolver()); - } - - @Bean - @Autowired - public FileManipulationRepositoryEventListener domainRepositoryEventListener(GlobalAdministrationConfiguration configuration, FileResourceStorage fileResourceStorage) { - return new FileManipulationRepositoryEventListener(configuration, fileResourceStorage); - } - - @Override - protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { - config.setDefaultPageSize(10); - config.setBaseUri(lightAdminConfiguration().getApplicationRestBaseUrl()); - config.exposeIdsFor(globalAdministrationConfiguration().getAllDomainTypesAsArray()); - config.setReturnBodyOnCreate(true); - config.setReturnBodyOnUpdate(true); - } - - @Override - public RequestMappingHandlerAdapter repositoryExporterHandlerAdapter() { - RequestMappingHandlerAdapter requestMappingHandlerAdapter = super.repositoryExporterHandlerAdapter(); - configureRepositoryExporterHandlerAdapter(requestMappingHandlerAdapter); - return requestMappingHandlerAdapter; - } - - @Override - protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { - validatingListener.addValidator("beforeCreate", validator()); - validatingListener.addValidator("beforeSave", validator()); - } - - @Override - public void addArgumentResolvers(List argumentResolvers) { - super.addArgumentResolvers(argumentResolvers); - argumentResolvers.add(configurationHandlerMethodArgumentResolver()); - } - - @Override - protected void configureJacksonObjectMapper(ObjectMapper objectMapper) { - objectMapper.registerModule(new LightAdminJacksonModule(globalAdministrationConfiguration())); - } - - @SuppressWarnings("unchecked") - private void configureRepositoryExporterHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) { - List defaultArgumentResolvers = (List) forDirectFieldAccess(requestMappingHandlerAdapter).getPropertyValue("argumentResolvers"); - - List argumentResolvers = decorateArgumentResolvers(defaultArgumentResolvers); - - argumentResolvers.add(configurationHandlerMethodArgumentResolver()); - - forDirectFieldAccess(requestMappingHandlerAdapter).setPropertyValue("argumentResolvers", argumentResolvers); - } - - private List decorateArgumentResolvers(List argumentResolvers) { - List result = newLinkedList(); - for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) { - if (isAssignableValue(PersistentEntityResourceAssemblerArgumentResolver.class, argumentResolver)) { - PersistentEntityResourceAssemblerArgumentResolver persistentEntityResourceAssemblerArgumentResolver = (PersistentEntityResourceAssemblerArgumentResolver) argumentResolver; - result.add(new DynamicPersistentEntityResourceAssemblerArgumentResolver(persistentEntityResourceAssemblerArgumentResolver)); - continue; - } - result.add(argumentResolver); - } - return result; - } - - private GlobalAdministrationConfiguration globalAdministrationConfiguration() { - return beanFactory.getBean(GlobalAdministrationConfiguration.class); - } - - private FileResourceStorage fileResourceStorage() { - return beanFactory.getBean(FileResourceStorage.class); - } - - private Validator validator() { - return beanFactory.getBean("validator", Validator.class); - } - - private LightAdminConfiguration lightAdminConfiguration() { - return beanFactory.getBean(LightAdminConfiguration.class); - } +/* + * Copyright 2012-2014 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.lightadmin.core.config.context; + +import com.fasterxml.jackson.databind.ObjectMapper; +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; +import org.lightadmin.core.persistence.support.DynamicDomainObjectMerger; +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.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.repository.support.RepositoryInvokerFactory; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; +import org.springframework.data.rest.core.support.DomainObjectMerger; +import org.springframework.data.rest.webmvc.RepositoryRestController; +import org.springframework.data.rest.webmvc.config.PersistentEntityResourceAssemblerArgumentResolver; +import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; +import org.springframework.validation.Validator; +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; + +@Configuration +@ComponentScan(basePackages = {"org.lightadmin.core.web"}, + includeFilters = @ComponentScan.Filter(RepositoryRestController.class), useDefaultFilters = false) +public class LightAdminRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration { + + @Autowired + private ListableBeanFactory beanFactory; + + @Bean + public DomainEntityLinks domainEntityLinks() { + return new DomainEntityLinks(globalAdministrationConfiguration(), backendIdConverterRegistry(), lightAdminConfiguration()); + } + + @Bean + public DynamicRepositoryEntityLinks dynamicRepositoryEntityLinks() { + return DynamicRepositoryEntityLinks.wrap(super.entityLinks()); + } + + @Bean + public DynamicPersistentEntityResourceProcessor dynamicPersistentEntityResourceProcessor() { + return new DynamicPersistentEntityResourceProcessor(globalAdministrationConfiguration(), fileResourceStorage(), dynamicRepositoryEntityLinks(), domainEntityLinks(), resourceMappings()); + } + + @Bean + 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()); + } + + @Bean + public RepositoryInvokerFactory repositoryInvokerFactory() { + RepositoryInvokerFactory repositoryInvokerFactory = super.repositoryInvokerFactory(); + + return new DynamicRepositoryInvokerFactory(repositories(), repositoryInvokerFactory); + } + + @Bean + public ConfigurationHandlerMethodArgumentResolver configurationHandlerMethodArgumentResolver() { + return new ConfigurationHandlerMethodArgumentResolver(globalAdministrationConfiguration(), resourceMetadataHandlerMethodArgumentResolver()); + } + + @Bean + @Autowired + public FileManipulationRepositoryEventListener domainRepositoryEventListener(GlobalAdministrationConfiguration configuration, FileResourceStorage fileResourceStorage) { + return new FileManipulationRepositoryEventListener(configuration, fileResourceStorage); + } + + @Override + protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { + config.setDefaultPageSize(10); + config.setBasePath(lightAdminConfiguration().getApplicationRestBasePath()); + config.exposeIdsFor(globalAdministrationConfiguration().getAllDomainTypesAsArray()); + config.setReturnBodyOnCreate(true); + config.setReturnBodyOnUpdate(true); + } + + @Override + public RequestMappingHandlerAdapter repositoryExporterHandlerAdapter() { + RequestMappingHandlerAdapter requestMappingHandlerAdapter = super.repositoryExporterHandlerAdapter(); + configureRepositoryExporterHandlerAdapter(requestMappingHandlerAdapter); + return requestMappingHandlerAdapter; + } + + @Override + protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { + validatingListener.addValidator("beforeCreate", validator()); + validatingListener.addValidator("beforeSave", validator()); + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + super.addArgumentResolvers(argumentResolvers); + argumentResolvers.add(configurationHandlerMethodArgumentResolver()); + } + + @Override + protected void configureJacksonObjectMapper(ObjectMapper objectMapper) { + objectMapper.registerModule(new LightAdminJacksonModule(globalAdministrationConfiguration())); + } + + @SuppressWarnings("unchecked") + private void configureRepositoryExporterHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) { + List defaultArgumentResolvers = (List) forDirectFieldAccess(requestMappingHandlerAdapter).getPropertyValue("argumentResolvers"); + + List argumentResolvers = decorateArgumentResolvers(defaultArgumentResolvers); + + argumentResolvers.add(configurationHandlerMethodArgumentResolver()); + + forDirectFieldAccess(requestMappingHandlerAdapter).setPropertyValue("argumentResolvers", argumentResolvers); + } + + private List decorateArgumentResolvers(List argumentResolvers) { + List result = newLinkedList(); + for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) { + if (isAssignableValue(PersistentEntityResourceAssemblerArgumentResolver.class, argumentResolver)) { + PersistentEntityResourceAssemblerArgumentResolver persistentEntityResourceAssemblerArgumentResolver = (PersistentEntityResourceAssemblerArgumentResolver) argumentResolver; + result.add(new DynamicPersistentEntityResourceAssemblerArgumentResolver(persistentEntityResourceAssemblerArgumentResolver)); + continue; + } + result.add(argumentResolver); + } + return result; + } + + private GlobalAdministrationConfiguration globalAdministrationConfiguration() { + return beanFactory.getBean(GlobalAdministrationConfiguration.class); + } + + private FileResourceStorage fileResourceStorage() { + return beanFactory.getBean(FileResourceStorage.class); + } + + private Validator validator() { + return beanFactory.getBean("validator", Validator.class); + } + + private LightAdminConfiguration lightAdminConfiguration() { + return beanFactory.getBean(LightAdminConfiguration.class); + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminSecurityConfiguration.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminSecurityConfiguration.java index 732790a0..0b129707 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminSecurityConfiguration.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminSecurityConfiguration.java @@ -1,211 +1,213 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.context; - -import org.lightadmin.core.config.LightAdminConfiguration; -import org.lightadmin.core.web.security.LightAdminRequestCache; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PropertiesLoaderUtils; -import org.springframework.security.access.AccessDecisionVoter; -import org.springframework.security.access.ConfigAttribute; -import org.springframework.security.access.SecurityConfig; -import org.springframework.security.access.vote.AffirmativeBased; -import org.springframework.security.access.vote.RoleVoter; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.ProviderManager; -import org.springframework.security.authentication.RememberMeAuthenticationProvider; -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; -import org.springframework.security.authentication.encoding.ShaPasswordEncoder; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.DefaultSecurityFilterChain; -import org.springframework.security.web.FilterChainProxy; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.access.AccessDeniedHandlerImpl; -import org.springframework.security.web.access.ExceptionTranslationFilter; -import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; -import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; -import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.authentication.logout.LogoutFilter; -import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; -import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; -import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; -import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.security.web.context.SecurityContextPersistenceFilter; -import org.springframework.security.web.savedrequest.RequestCache; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.AnyRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; - -import javax.servlet.Filter; -import java.io.IOException; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Properties; - -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Maps.newLinkedHashMap; -import static java.util.Arrays.asList; - -@Configuration -public class LightAdminSecurityConfiguration { - - private static final String REMEMBER_ME_DIGEST_KEY = "LightAdmin"; - private static final String ROLE_ADMIN = "ROLE_ADMIN"; - - private static final String[] PUBLIC_RESOURCES = { - "/images/**", "/scripts/**", "/styles/**", - "/rest/**/file", - "/login", "/page-not-found", "/access-denied", - "/dynamic/logo" - }; - - @Value("classpath:users.properties") - private Resource usersResource; - - @Autowired - private LightAdminConfiguration lightAdminConfiguration; - - @Bean - @Autowired - public FilterChainProxy springSecurityFilterChain(Filter filterSecurityInterceptor, Filter authenticationFilter, Filter rememberMeAuthenticationFilter, Filter logoutFilter, Filter exceptionTranslationFilter, Filter securityContextPersistenceFilter) { - List filterChains = newArrayList(); - for (String pattern : PUBLIC_RESOURCES) { - filterChains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher(applicationUrl(pattern)))); - } - - filterChains.add(new DefaultSecurityFilterChain(AnyRequestMatcher.INSTANCE, securityContextPersistenceFilter, exceptionTranslationFilter, logoutFilter, authenticationFilter, rememberMeAuthenticationFilter, filterSecurityInterceptor)); - - return new FilterChainProxy(filterChains); - } - - @Bean - @Autowired - public Filter filterSecurityInterceptor(AuthenticationManager authenticationManager) throws Exception { - FilterSecurityInterceptor filter = new FilterSecurityInterceptor(); - filter.setAuthenticationManager(authenticationManager); - filter.setAccessDecisionManager(new AffirmativeBased(asList((AccessDecisionVoter) new RoleVoter()))); - filter.setSecurityMetadataSource(securityMetadataSource()); - filter.afterPropertiesSet(); - return filter; - } - - private FilterInvocationSecurityMetadataSource securityMetadataSource() { - LinkedHashMap> map = newLinkedHashMap(); - map.put(AnyRequestMatcher.INSTANCE, asList((ConfigAttribute) new SecurityConfig(ROLE_ADMIN))); - return new DefaultFilterInvocationSecurityMetadataSource(map); - } - - @Bean - @Autowired - public Filter authenticationFilter(AuthenticationManager authenticationManager, RequestCache requestCache) { - UsernamePasswordAuthenticationFilter authenticationFilter = new UsernamePasswordAuthenticationFilter(); - authenticationFilter.setFilterProcessesUrl(applicationUrl("/j_spring_security_check")); - authenticationFilter.setAuthenticationManager(authenticationManager); - SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); - successHandler.setRequestCache(requestCache); - authenticationFilter.setAuthenticationSuccessHandler(successHandler); - authenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(applicationUrl("/login?login_error=1"))); - return authenticationFilter; - } - - @Bean - public Filter exceptionTranslationFilter(RequestCache requestCache) { - AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl(); - accessDeniedHandler.setErrorPage(applicationUrl("/access-denied")); - LoginUrlAuthenticationEntryPoint authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint(applicationUrl("/login")); - ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(authenticationEntryPoint, requestCache); - exceptionTranslationFilter.setAccessDeniedHandler(accessDeniedHandler); - return exceptionTranslationFilter; - } - - @Bean - public Filter logoutFilter() { - SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler(); - logoutHandler.setInvalidateHttpSession(false); - LogoutFilter logoutFilter = new LogoutFilter(applicationUrl("/"), logoutHandler); - logoutFilter.setFilterProcessesUrl(applicationUrl("/logout")); - return logoutFilter; - } - - @Bean - public Filter securityContextPersistenceFilter() { - HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository(); - repo.setSpringSecurityContextKey(keyWithNamespace(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY)); - return new SecurityContextPersistenceFilter(repo); - } - - @Bean - public Filter rememberMeAuthenticationFilter(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) { - TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices(REMEMBER_ME_DIGEST_KEY, userDetailsService); - rememberMeServices.setCookieName(keyWithNamespace(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY)); - return new RememberMeAuthenticationFilter(authenticationManager, rememberMeServices); - } - - @Bean - public RequestCache requestCache() { - return new LightAdminRequestCache(); - } - - @Bean - @Autowired - public AuthenticationManager authenticationManager(AuthenticationProvider authenticationProvider, AuthenticationProvider rememberMeAuthenticationProvider) { - return new ProviderManager(asList(authenticationProvider, rememberMeAuthenticationProvider)); - } - - @Bean - @Autowired - public AuthenticationProvider authenticationProvider(UserDetailsService usersService) throws Exception { - DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); - provider.setPasswordEncoder(new ShaPasswordEncoder()); - provider.setUserDetailsService(usersService); - provider.afterPropertiesSet(); - return provider; - } - - @Bean - @Primary - public UserDetailsService userDetailsService() throws IOException { - Properties usersPproperties = PropertiesLoaderUtils.loadProperties(usersResource); - return new InMemoryUserDetailsManager(usersPproperties); - } - - @Bean - public AuthenticationProvider rememberMeAuthenticationProvider() { - return new RememberMeAuthenticationProvider(REMEMBER_ME_DIGEST_KEY); - } - - private String applicationUrl(String path) { - return lightAdminConfiguration.getApplicationUrl(path); - } - - private String keyWithNamespace(String key) { - return "lightadmin:" + key; - } - -} +/* + * Copyright 2012-2014 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.lightadmin.core.config.context; + +import org.lightadmin.core.config.LightAdminConfiguration; +import org.lightadmin.core.web.security.LightAdminRequestCache; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PropertiesLoaderUtils; +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.SecurityConfig; +import org.springframework.security.access.vote.AffirmativeBased; +import org.springframework.security.access.vote.RoleVoter; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.RememberMeAuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.authentication.encoding.ShaPasswordEncoder; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.DefaultSecurityFilterChain; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.access.AccessDeniedHandlerImpl; +import org.springframework.security.web.access.ExceptionTranslationFilter; +import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; +import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; +import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; +import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter; +import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextPersistenceFilter; +import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.AnyRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import javax.servlet.Filter; +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Properties; + +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Maps.newLinkedHashMap; +import static java.util.Arrays.asList; + +@Configuration +public class LightAdminSecurityConfiguration { + + private static final String REMEMBER_ME_DIGEST_KEY = "LightAdmin"; + private static final String ROLE_ADMIN = "ROLE_ADMIN"; + + private static final String[] PUBLIC_RESOURCES = { + "/images/**", "/scripts/**", "/styles/**", + "/rest/**/file", + "/login", "/page-not-found", "/access-denied", + "/dynamic/logo" + }; + + @Value("classpath:users.properties") + private Resource usersResource; + + @Autowired + private LightAdminConfiguration lightAdminConfiguration; + + @Bean + @Autowired + public FilterChainProxy springSecurityFilterChain(Filter filterSecurityInterceptor, Filter authenticationFilter, Filter rememberMeAuthenticationFilter, Filter logoutFilter, Filter exceptionTranslationFilter, Filter securityContextPersistenceFilter) { + List filterChains = newArrayList(); + for (String pattern : PUBLIC_RESOURCES) { + filterChains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher(applicationUrl(pattern)))); + } + + filterChains.add(new DefaultSecurityFilterChain(AnyRequestMatcher.INSTANCE, securityContextPersistenceFilter, exceptionTranslationFilter, logoutFilter, authenticationFilter, rememberMeAuthenticationFilter, filterSecurityInterceptor)); + + return new FilterChainProxy(filterChains); + } + + @Bean + @Autowired + public Filter filterSecurityInterceptor(AuthenticationManager authenticationManager) throws Exception { + FilterSecurityInterceptor filter = new FilterSecurityInterceptor(); + filter.setAuthenticationManager(authenticationManager); + List> decisionVoters = asList((AccessDecisionVoter) new RoleVoter()); + AffirmativeBased accessDecisionManager = new AffirmativeBased(decisionVoters); + filter.setAccessDecisionManager(accessDecisionManager); + filter.setSecurityMetadataSource(securityMetadataSource()); + filter.afterPropertiesSet(); + return filter; + } + + private FilterInvocationSecurityMetadataSource securityMetadataSource() { + LinkedHashMap> map = newLinkedHashMap(); + map.put(AnyRequestMatcher.INSTANCE, asList((ConfigAttribute) new SecurityConfig(ROLE_ADMIN))); + return new DefaultFilterInvocationSecurityMetadataSource(map); + } + + @Bean + @Autowired + public Filter authenticationFilter(AuthenticationManager authenticationManager, RequestCache requestCache) { + UsernamePasswordAuthenticationFilter authenticationFilter = new UsernamePasswordAuthenticationFilter(); + authenticationFilter.setFilterProcessesUrl(applicationUrl("/j_spring_security_check")); + authenticationFilter.setAuthenticationManager(authenticationManager); + SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); + successHandler.setRequestCache(requestCache); + authenticationFilter.setAuthenticationSuccessHandler(successHandler); + authenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(applicationUrl("/login?login_error=1"))); + return authenticationFilter; + } + + @Bean + public Filter exceptionTranslationFilter(RequestCache requestCache) { + AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl(); + accessDeniedHandler.setErrorPage(applicationUrl("/access-denied")); + LoginUrlAuthenticationEntryPoint authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint(applicationUrl("/login")); + ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(authenticationEntryPoint, requestCache); + exceptionTranslationFilter.setAccessDeniedHandler(accessDeniedHandler); + return exceptionTranslationFilter; + } + + @Bean + public Filter logoutFilter() { + SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler(); + logoutHandler.setInvalidateHttpSession(false); + LogoutFilter logoutFilter = new LogoutFilter(applicationUrl("/"), logoutHandler); + logoutFilter.setFilterProcessesUrl(applicationUrl("/logout")); + return logoutFilter; + } + + @Bean + public Filter securityContextPersistenceFilter() { + HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository(); + repo.setSpringSecurityContextKey(keyWithNamespace(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY)); + return new SecurityContextPersistenceFilter(repo); + } + + @Bean + public Filter rememberMeAuthenticationFilter(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) { + TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices(REMEMBER_ME_DIGEST_KEY, userDetailsService); + rememberMeServices.setCookieName(keyWithNamespace(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY)); + return new RememberMeAuthenticationFilter(authenticationManager, rememberMeServices); + } + + @Bean + public RequestCache requestCache() { + return new LightAdminRequestCache(); + } + + @Bean + @Autowired + public AuthenticationManager authenticationManager(AuthenticationProvider authenticationProvider, AuthenticationProvider rememberMeAuthenticationProvider) { + return new ProviderManager(asList(authenticationProvider, rememberMeAuthenticationProvider)); + } + + @Bean + @Autowired + public AuthenticationProvider authenticationProvider(UserDetailsService usersService) throws Exception { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setPasswordEncoder(new ShaPasswordEncoder()); + provider.setUserDetailsService(usersService); + provider.afterPropertiesSet(); + return provider; + } + + @Bean + @Primary + public UserDetailsService userDetailsService() throws IOException { + Properties usersPproperties = PropertiesLoaderUtils.loadProperties(usersResource); + return new InMemoryUserDetailsManager(usersPproperties); + } + + @Bean + public AuthenticationProvider rememberMeAuthenticationProvider() { + return new RememberMeAuthenticationProvider(REMEMBER_ME_DIGEST_KEY); + } + + private String applicationUrl(String path) { + return lightAdminConfiguration.getApplicationUrl(path); + } + + private String keyWithNamespace(String key) { + return "lightadmin:" + key; + } + +} diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvoker.java b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvoker.java index 7747c811..0b19154f 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvoker.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvoker.java @@ -1,35 +1,35 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.persistence.repository.invoker; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.rest.core.invoke.RepositoryInvoker; - -import java.util.List; - -public interface DynamicRepositoryInvoker extends RepositoryInvoker { - - Page findAll(Specification spec, Pageable pageable); - - List findAll(Specification spec, Sort sort); - - List findAll(Specification spec); - - long count(Specification spec); +/* + * Copyright 2012-2014 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.lightadmin.core.persistence.repository.invoker; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.repository.support.RepositoryInvoker; + +import java.util.List; + +public interface DynamicRepositoryInvoker extends RepositoryInvoker { + + Page findAll(Specification spec, Pageable pageable); + + List findAll(Specification spec, Sort sort); + + List findAll(Specification spec); + + long count(Specification spec); } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerFactory.java b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerFactory.java index a58a6faf..5dc08726 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerFactory.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerFactory.java @@ -1,40 +1,40 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.persistence.repository.invoker; - -import org.lightadmin.core.persistence.repository.DynamicJpaRepository; -import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.core.invoke.RepositoryInvoker; -import org.springframework.data.rest.core.invoke.RepositoryInvokerFactory; - -public class DynamicRepositoryInvokerFactory implements RepositoryInvokerFactory { - - private final RepositoryInvokerFactory delegate; - private final Repositories repositories; - - public DynamicRepositoryInvokerFactory(Repositories repositories, RepositoryInvokerFactory repositoryInvokerFactory) { - this.repositories = repositories; - this.delegate = repositoryInvokerFactory; - } - - @Override - public RepositoryInvoker getInvokerFor(Class domainType) { - DynamicJpaRepository dynamicJpaRepository = (DynamicJpaRepository) repositories.getRepositoryFor(domainType); - RepositoryInvoker repositoryInvoker = delegate.getInvokerFor(domainType); - - return new DynamicRepositoryInvokerWrapper(dynamicJpaRepository, repositoryInvoker); - } +/* + * Copyright 2012-2014 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.lightadmin.core.persistence.repository.invoker; + +import org.lightadmin.core.persistence.repository.DynamicJpaRepository; +import org.springframework.data.repository.support.Repositories; +import org.springframework.data.repository.support.RepositoryInvoker; +import org.springframework.data.repository.support.RepositoryInvokerFactory; + +public class DynamicRepositoryInvokerFactory implements RepositoryInvokerFactory { + + private final RepositoryInvokerFactory delegate; + private final Repositories repositories; + + public DynamicRepositoryInvokerFactory(Repositories repositories, RepositoryInvokerFactory repositoryInvokerFactory) { + this.repositories = repositories; + this.delegate = repositoryInvokerFactory; + } + + @Override + public RepositoryInvoker getInvokerFor(Class domainType) { + DynamicJpaRepository dynamicJpaRepository = (DynamicJpaRepository) repositories.getRepositoryFor(domainType); + RepositoryInvoker repositoryInvoker = delegate.getInvokerFor(domainType); + + return new DynamicRepositoryInvokerWrapper(dynamicJpaRepository, repositoryInvoker); + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerWrapper.java b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerWrapper.java index 75fe6f09..bd89b6f5 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerWrapper.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/persistence/repository/invoker/DynamicRepositoryInvokerWrapper.java @@ -1,130 +1,117 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.persistence.repository.invoker; - -import org.lightadmin.core.persistence.repository.DynamicJpaRepository; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.rest.core.invoke.RepositoryInvoker; - -import java.io.Serializable; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; - -@SuppressWarnings("unchecked") -public class DynamicRepositoryInvokerWrapper implements DynamicRepositoryInvoker { - - private final DynamicJpaRepository repository; - private final RepositoryInvoker repositoryInvoker; - - public DynamicRepositoryInvokerWrapper(DynamicJpaRepository dynamicRepository, RepositoryInvoker repositoryInvoker) { - this.repository = dynamicRepository; - this.repositoryInvoker = repositoryInvoker; - } - - @Override - public Page findAll(Specification spec, Pageable pageable) { - return repository.findAll(spec, pageable); - } - - @Override - public List findAll(Specification spec, Sort sort) { - return repository.findAll(spec, sort); - } - - @Override - public List findAll(Specification spec) { - return repository.findAll(spec); - } - - @Override - public long count(Specification spec) { - return repository.count(spec); - } - - @Override - public T invokeSave(T object) { - return repositoryInvoker.invokeSave(object); - } - - @Override - public T invokeFindOne(Serializable id) { - return repositoryInvoker.invokeFindOne(id); - } - - @Override - public Iterable invokeFindAll(Pageable pageable) { - return repositoryInvoker.invokeFindAll(pageable); - } - - @Override - public Iterable invokeFindAll(Sort sort) { - return repositoryInvoker.invokeFindAll(sort); - } - - @Override - public void invokeDelete(Serializable serializable) { - repositoryInvoker.invokeDelete(serializable); - } - - @Override - public Object invokeQueryMethod(Method method, Map parameters, Pageable pageable, Sort sort) { - return repositoryInvoker.invokeQueryMethod(method, parameters, pageable, sort); - } - - @Override - public boolean hasSaveMethod() { - return repositoryInvoker.hasSaveMethod(); - } - - @Override - public boolean exposesSave() { - return repositoryInvoker.exposesSave(); - } - - @Override - public boolean hasDeleteMethod() { - return repositoryInvoker.hasDeleteMethod(); - } - - @Override - public boolean exposesDelete() { - return repositoryInvoker.exposesDelete(); - } - - @Override - public boolean hasFindOneMethod() { - return repositoryInvoker.hasFindOneMethod(); - } - - @Override - public boolean exposesFindOne() { - return repositoryInvoker.exposesFindOne(); - } - - @Override - public boolean hasFindAllMethod() { - return repositoryInvoker.hasFindAllMethod(); - } - - @Override - public boolean exposesFindAll() { - return repositoryInvoker.exposesFindAll(); - } +/* + * Copyright 2012-2014 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.lightadmin.core.persistence.repository.invoker; + +import org.lightadmin.core.persistence.repository.DynamicJpaRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.repository.support.RepositoryInvoker; +import org.springframework.util.MultiValueMap; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unchecked") +public class DynamicRepositoryInvokerWrapper implements DynamicRepositoryInvoker { + + private final DynamicJpaRepository repository; + private final RepositoryInvoker repositoryInvoker; + + public DynamicRepositoryInvokerWrapper(DynamicJpaRepository dynamicRepository, RepositoryInvoker repositoryInvoker) { + this.repository = dynamicRepository; + this.repositoryInvoker = repositoryInvoker; + } + + @Override + public Page findAll(Specification spec, Pageable pageable) { + return repository.findAll(spec, pageable); + } + + @Override + public List findAll(Specification spec, Sort sort) { + return repository.findAll(spec, sort); + } + + @Override + public List findAll(Specification spec) { + return repository.findAll(spec); + } + + @Override + public long count(Specification spec) { + return repository.count(spec); + } + + @Override + public T invokeSave(T object) { + return repositoryInvoker.invokeSave(object); + } + + @Override + public T invokeFindOne(Serializable id) { + return repositoryInvoker.invokeFindOne(id); + } + + @Override + public Iterable invokeFindAll(Pageable pageable) { + return repositoryInvoker.invokeFindAll(pageable); + } + + @Override + public Iterable invokeFindAll(Sort sort) { + return repositoryInvoker.invokeFindAll(sort); + } + + @Override + public void invokeDelete(Serializable serializable) { + repositoryInvoker.invokeDelete(serializable); + } + + @Override + public Object invokeQueryMethod(Method method, Map parameters, Pageable pageable, Sort sort) { + return repositoryInvoker.invokeQueryMethod(method, parameters, pageable, sort); + } + + @Override + public Object invokeQueryMethod(Method method, MultiValueMap parameters, + Pageable pageable, Sort sort) { + return repositoryInvoker.invokeQueryMethod(method, parameters, pageable, sort); + } + + @Override + public boolean hasSaveMethod() { + return repositoryInvoker.hasSaveMethod(); + } + + @Override + public boolean hasDeleteMethod() { + return repositoryInvoker.hasDeleteMethod(); + } + + @Override + public boolean hasFindOneMethod() { + return repositoryInvoker.hasFindOneMethod(); + } + + @Override + public boolean hasFindAllMethod() { + return repositoryInvoker.hasFindAllMethod(); + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/RepositoryFilePropertyController.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/RepositoryFilePropertyController.java index 4772104a..97af2c48 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/RepositoryFilePropertyController.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/RepositoryFilePropertyController.java @@ -1,191 +1,191 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.web; - -import org.lightadmin.core.storage.FileResourceStorage; -import org.lightadmin.core.web.support.DynamicRepositoryEntityLinks; -import org.lightadmin.core.web.support.FilePropertyValue; -import org.lightadmin.core.web.support.FileResourceLoader; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.rest.core.invoke.RepositoryInvoker; -import org.springframework.data.rest.webmvc.RepositoryRestController; -import org.springframework.data.rest.webmvc.ResourceNotFoundException; -import org.springframework.data.rest.webmvc.RootResourceInformation; -import org.springframework.data.rest.webmvc.support.BackendId; -import org.springframework.hateoas.Link; -import org.springframework.hateoas.Resource; -import org.springframework.hateoas.ResourceSupport; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.Serializable; -import java.util.Map; - -import static org.lightadmin.core.persistence.metamodel.PersistentPropertyType.isOfFileType; -import static org.springframework.data.rest.webmvc.ControllerUtils.toEmptyResponse; -import static org.springframework.data.rest.webmvc.ControllerUtils.toResponseEntity; -import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED; -import static org.springframework.http.HttpStatus.OK; -import static org.springframework.web.bind.annotation.RequestMethod.*; - -@RepositoryRestController -public class RepositoryFilePropertyController { - - private static final String BASE_MAPPING = "/{repository}/{id}/{property}"; - - private BeanFactory beanFactory; - - @Autowired - public RepositoryFilePropertyController(BeanFactory beanFactory) { - this.beanFactory = beanFactory; - } - - @RequestMapping(value = BASE_MAPPING + "/file", method = GET) - public void filePropertyOfEntity(RootResourceInformation repoRequest, ServletResponse response, @BackendId Serializable id, @PathVariable String property) throws Exception { - PersistentEntity persistentEntity = repoRequest.getPersistentEntity(); - RepositoryInvoker invoker = repoRequest.getInvoker(); - - Object domainObj = invoker.invokeFindOne(id); - - if (null == domainObj) { - throw new ResourceNotFoundException(); - } - - PersistentProperty prop = persistentEntity.getPersistentProperty(property); - if (null == prop) { - throw new ResourceNotFoundException(); - } - - if (isOfFileType(prop)) { - fileResourceLoader().downloadFile(domainObj, prop, (HttpServletResponse) response); - } - } - - @RequestMapping(value = BASE_MAPPING + "/binary", method = GET) - public ResponseEntity filePropertyValueOfEntity(RootResourceInformation repoRequest, @BackendId Serializable id, @PathVariable String property) throws Exception { - PersistentEntity persistentEntity = repoRequest.getPersistentEntity(); - RepositoryInvoker invoker = repoRequest.getInvoker(); - - Object domainObj = invoker.invokeFindOne(id); - - if (null == domainObj) { - throw new ResourceNotFoundException(); - } - - PersistentProperty prop = persistentEntity.getPersistentProperty(property); - if (null == prop) { - throw new ResourceNotFoundException(); - } - - if (isOfFileType(prop)) { - return toResponseEntity(OK, new HttpHeaders(), new Resource(evaluateFilePropertyValue(domainObj, prop))); - } - - return toEmptyResponse(METHOD_NOT_ALLOWED); - } - - @RequestMapping(value = BASE_MAPPING + "/file", method = DELETE) - public ResponseEntity deleteFileOfPropertyOfEntity(RootResourceInformation repoRequest, @BackendId Serializable id, @PathVariable String property) throws Exception { - PersistentEntity persistentEntity = repoRequest.getPersistentEntity(); - RepositoryInvoker invoker = repoRequest.getInvoker(); - - Object domainObj = invoker.invokeFindOne(id); - - if (null == domainObj) { - throw new ResourceNotFoundException(); - } - - PersistentProperty prop = persistentEntity.getPersistentProperty(property); - if (null == prop) { - throw new ResourceNotFoundException(); - } - - if (!isOfFileType(prop)) { - return toEmptyResponse(METHOD_NOT_ALLOWED); - } - - fileResourceStorage().delete(domainObj, prop); - - invoker.invokeSave(domainObj); - - return toEmptyResponse(OK); - } - - @RequestMapping(value = BASE_MAPPING + "/file", method = {POST}) - public ResponseEntity saveFilePropertyOfEntity(final ServletServerHttpRequest request) throws Exception { - final MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request.getServletRequest(); - - final Map fileMap = multipartHttpServletRequest.getFileMap(); - - if (!fileMap.isEmpty()) { - final Map.Entry fileEntry = fileMap.entrySet().iterator().next(); - - return toResponseEntity(OK, new HttpHeaders(), fileResource(fileEntry)); - } - - return toEmptyResponse(METHOD_NOT_ALLOWED); - } - - private FilePropertyValue evaluateFilePropertyValue(Object instance, PersistentProperty persistentProperty) { - FileResourceStorage fileResourceStorage = fileResourceStorage(); - - try { - if (!fileResourceStorage.fileExists(instance, persistentProperty)) { - return new FilePropertyValue(false); - } - - Link fileLink = entityLinks().linkForFilePropertyLink(instance, persistentProperty); - - byte[] fileData = fileResourceStorage.load(instance, persistentProperty); - - return new FilePropertyValue(fileLink, fileData); - - } catch (Exception e) { - throw new ResourceNotFoundException(e.getMessage()); - } - } - - private Resource fileResource(Map.Entry fileEntry) throws IOException { - MultipartFile multipartFile = fileEntry.getValue(); - - FilePropertyValue filePropertyValue = new FilePropertyValue(multipartFile.getOriginalFilename(), multipartFile.getBytes()); - - return new Resource(filePropertyValue); - } - - private FileResourceLoader fileResourceLoader() { - return beanFactory.getBean(FileResourceLoader.class); - } - - private FileResourceStorage fileResourceStorage() { - return beanFactory.getBean(FileResourceStorage.class); - } - - private DynamicRepositoryEntityLinks entityLinks() { - return beanFactory.getBean(DynamicRepositoryEntityLinks.class); - } +/* + * Copyright 2012-2014 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.lightadmin.core.web; + +import org.lightadmin.core.storage.FileResourceStorage; +import org.lightadmin.core.web.support.DynamicRepositoryEntityLinks; +import org.lightadmin.core.web.support.FilePropertyValue; +import org.lightadmin.core.web.support.FileResourceLoader; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.PersistentProperty; +import org.springframework.data.repository.support.RepositoryInvoker; +import org.springframework.data.rest.webmvc.RepositoryRestController; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.data.rest.webmvc.RootResourceInformation; +import org.springframework.data.rest.webmvc.support.BackendId; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.Resource; +import org.springframework.hateoas.ResourceSupport; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Serializable; +import java.util.Map; + +import static org.lightadmin.core.persistence.metamodel.PersistentPropertyType.isOfFileType; +import static org.springframework.data.rest.webmvc.ControllerUtils.toEmptyResponse; +import static org.springframework.data.rest.webmvc.ControllerUtils.toResponseEntity; +import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED; +import static org.springframework.http.HttpStatus.OK; +import static org.springframework.web.bind.annotation.RequestMethod.*; + +@RepositoryRestController +public class RepositoryFilePropertyController { + + private static final String BASE_MAPPING = "/{repository}/{id}/{property}"; + + private BeanFactory beanFactory; + + @Autowired + public RepositoryFilePropertyController(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + @RequestMapping(value = BASE_MAPPING + "/file", method = GET) + public void filePropertyOfEntity(RootResourceInformation repoRequest, ServletResponse response, @BackendId Serializable id, @PathVariable String property) throws Exception { + PersistentEntity persistentEntity = repoRequest.getPersistentEntity(); + RepositoryInvoker invoker = repoRequest.getInvoker(); + + Object domainObj = invoker.invokeFindOne(id); + + if (null == domainObj) { + throw new ResourceNotFoundException(); + } + + PersistentProperty prop = persistentEntity.getPersistentProperty(property); + if (null == prop) { + throw new ResourceNotFoundException(); + } + + if (isOfFileType(prop)) { + fileResourceLoader().downloadFile(domainObj, prop, (HttpServletResponse) response); + } + } + + @RequestMapping(value = BASE_MAPPING + "/binary", method = GET) + public ResponseEntity filePropertyValueOfEntity(RootResourceInformation repoRequest, @BackendId Serializable id, @PathVariable String property) throws Exception { + PersistentEntity persistentEntity = repoRequest.getPersistentEntity(); + RepositoryInvoker invoker = repoRequest.getInvoker(); + + Object domainObj = invoker.invokeFindOne(id); + + if (null == domainObj) { + throw new ResourceNotFoundException(); + } + + PersistentProperty prop = persistentEntity.getPersistentProperty(property); + if (null == prop) { + throw new ResourceNotFoundException(); + } + + if (isOfFileType(prop)) { + return toResponseEntity(OK, new HttpHeaders(), new Resource(evaluateFilePropertyValue(domainObj, prop))); + } + + return toEmptyResponse(METHOD_NOT_ALLOWED); + } + + @RequestMapping(value = BASE_MAPPING + "/file", method = DELETE) + public ResponseEntity deleteFileOfPropertyOfEntity(RootResourceInformation repoRequest, @BackendId Serializable id, @PathVariable String property) throws Exception { + PersistentEntity persistentEntity = repoRequest.getPersistentEntity(); + RepositoryInvoker invoker = repoRequest.getInvoker(); + + Object domainObj = invoker.invokeFindOne(id); + + if (null == domainObj) { + throw new ResourceNotFoundException(); + } + + PersistentProperty prop = persistentEntity.getPersistentProperty(property); + if (null == prop) { + throw new ResourceNotFoundException(); + } + + if (!isOfFileType(prop)) { + return toEmptyResponse(METHOD_NOT_ALLOWED); + } + + fileResourceStorage().delete(domainObj, prop); + + invoker.invokeSave(domainObj); + + return toEmptyResponse(OK); + } + + @RequestMapping(value = BASE_MAPPING + "/file", method = {POST}) + public ResponseEntity saveFilePropertyOfEntity(final ServletServerHttpRequest request) throws Exception { + final MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request.getServletRequest(); + + final Map fileMap = multipartHttpServletRequest.getFileMap(); + + if (!fileMap.isEmpty()) { + final Map.Entry fileEntry = fileMap.entrySet().iterator().next(); + + return toResponseEntity(OK, new HttpHeaders(), fileResource(fileEntry)); + } + + return toEmptyResponse(METHOD_NOT_ALLOWED); + } + + private FilePropertyValue evaluateFilePropertyValue(Object instance, PersistentProperty persistentProperty) { + FileResourceStorage fileResourceStorage = fileResourceStorage(); + + try { + if (!fileResourceStorage.fileExists(instance, persistentProperty)) { + return new FilePropertyValue(false); + } + + Link fileLink = entityLinks().linkForFilePropertyLink(instance, persistentProperty); + + byte[] fileData = fileResourceStorage.load(instance, persistentProperty); + + return new FilePropertyValue(fileLink, fileData); + + } catch (Exception e) { + throw new ResourceNotFoundException(e.getMessage()); + } + } + + private Resource fileResource(Map.Entry fileEntry) throws IOException { + MultipartFile multipartFile = fileEntry.getValue(); + + FilePropertyValue filePropertyValue = new FilePropertyValue(multipartFile.getOriginalFilename(), multipartFile.getBytes()); + + return new Resource(filePropertyValue); + } + + private FileResourceLoader fileResourceLoader() { + return beanFactory.getBean(FileResourceLoader.class); + } + + private FileResourceStorage fileResourceStorage() { + return beanFactory.getBean(FileResourceStorage.class); + } + + private DynamicRepositoryEntityLinks entityLinks() { + return beanFactory.getBean(DynamicRepositoryEntityLinks.class); + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java index 827b5158..f8a09d9f 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java @@ -1,84 +1,89 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.web.support; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.core.mapping.ResourceMappings; -import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler; -import org.springframework.data.rest.webmvc.support.Projector; -import org.springframework.hateoas.EntityLinks; -import org.springframework.hateoas.Link; -import org.springframework.util.Assert; - -import java.io.Serializable; - -import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; - -/** - * Fix of Spring Data REST related defect - * - * @author Maxim Kharchenko (kharchenko.max@gmail.com) - */ -public class DynamicPersistentEntityResourceAssembler extends PersistentEntityResourceAssembler { - - public DynamicPersistentEntityResourceAssembler(PersistentEntityResourceAssembler resourceAssembler) { - super(repositories(resourceAssembler), entityLinks(resourceAssembler), projector(resourceAssembler), mappings(resourceAssembler)); - } - - /** - * @see DATAREST-269 (https://jira.spring.io/browse/DATAREST-269) - */ - @Override - public Link getSelfLinkFor(Object instance) { - Assert.notNull(instance, "Domain object must not be null!"); - - Repositories repositories = repositories(this); - - Class instanceType = instance.getClass(); - PersistentEntity entity = repositories.getPersistentEntity(instanceType); - - if (entity == null) { - throw new IllegalArgumentException(String.format("Cannot create self link for %s! No persistent entity found!", instanceType)); - } - - EntityInformation entityInformation = repositories.getEntityInformationFor(instanceType); - Serializable id = entityInformation.getId(instance); - - if (id == null) { - return entityLinks(this).linkToCollectionResource(entity.getType()).withSelfRel(); - } - - return entityLinks(this).linkToSingleResource(entity.getType(), id).withSelfRel(); - } - - private static Repositories repositories(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (Repositories) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("repositories"); - } - - private static EntityLinks entityLinks(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (EntityLinks) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("entityLinks"); - } - - private static Projector projector(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (Projector) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("projector"); - } - - private static ResourceMappings mappings(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (ResourceMappings) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("mappings"); - } +/* + * Copyright 2012-2014 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.lightadmin.core.web.support; + +import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.data.repository.core.EntityInformation; +import org.springframework.data.repository.support.Repositories; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler; +import org.springframework.data.rest.webmvc.support.Projector; +import org.springframework.hateoas.EntityLinks; +import org.springframework.hateoas.Link; +import org.springframework.util.Assert; + +import java.io.Serializable; + +import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; + +/** + * Fix of Spring Data REST related defect + * + * @author Maxim Kharchenko (kharchenko.max@gmail.com) + */ +public class DynamicPersistentEntityResourceAssembler extends PersistentEntityResourceAssembler { + + public DynamicPersistentEntityResourceAssembler(PersistentEntityResourceAssembler resourceAssembler) { + super(entities(resourceAssembler), entityLinks(resourceAssembler), projector(resourceAssembler), mappings(resourceAssembler)); + } + + /** + * @see DATAREST-269 (https://jira.spring.io/browse/DATAREST-269) + */ + @Override + public Link getSelfLinkFor(Object instance) { + Assert.notNull(instance, "Domain object must not be null!"); + + Repositories repositories = repositories(this); + + Class instanceType = instance.getClass(); + PersistentEntity entity = repositories.getPersistentEntity(instanceType); + + if (entity == null) { + throw new IllegalArgumentException(String.format("Cannot create self link for %s! No persistent entity found!", instanceType)); + } + + EntityInformation entityInformation = repositories.getEntityInformationFor(instanceType); + Serializable id = entityInformation.getId(instance); + + if (id == null) { + return entityLinks(this).linkToCollectionResource(entity.getType()).withSelfRel(); + } + + return entityLinks(this).linkToSingleResource(entity.getType(), id).withSelfRel(); + } + + private static Repositories repositories(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (Repositories) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("repositories"); + } + + private static EntityLinks entityLinks(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (EntityLinks) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("entityLinks"); + } + + private static Projector projector(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (Projector) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("projector"); + } + + private static ResourceMappings mappings(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (ResourceMappings) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("mappings"); + } + + private static PersistentEntities entities(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (PersistentEntities) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("entities"); + } } \ No newline at end of file diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 02d28756..b9fda459 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.0.BUILD-SNAPSHOT + 1.3.1.BUILD-SNAPSHOT lightadmin-sandbox - 1.2.0.BUILD-SNAPSHOT + 1.3.1.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 79c30063..2ace6e5e 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -1,235 +1,235 @@ - - - - 4.0.0 - - - org.lightadmin - lightadmin-parent - 1.2.0.BUILD-SNAPSHOT - - - lightadmin-tests - 1.2.0.BUILD-SNAPSHOT - - LightAdmin Selenium - - - 8080 - - 2.45.0 - 1.4.01 - - - - - org.lightadmin - lightadmin-sandbox - ${project.version} - war - - - org.lightadmin - lightadmin-sandbox - ${project.version} - classes - - - - org.seleniumhq.selenium - selenium-java - ${selenium-java.version} - - - - xml-apis - xml-apis - ${xml-apis.version} - - - - com.google.guava - guava - - - - org.slf4j - slf4j-api - - - ch.qos.logback - logback-classic - runtime - - - - org.springframework - spring-core - - - commons-logging - commons-logging - - - - - org.springframework - spring-context - - - - javax.servlet.jsp - javax.servlet.jsp-api - - - - org.springframework - spring-test - - - junit - junit - - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.12 - - - integration-test - integration-test - - integration-test - - - - **/*.class - - true - - - - verify - verify - - verify - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.12 - - true - - - - - - - - - test-mode - - - mode - test - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - dev-mode - - - mode - dev - - - - - - org.codehaus.cargo - cargo-maven2-plugin - 1.2.4 - - - start-cargo - pre-integration-test - - start - - - - stop-cargo - post-integration-test - - stop - - - - - - jetty8x - - org.eclipse.jetty - jetty-distribution - 8.1.8.v20121106 - - - - - ${project.groupId} - lightadmin-sandbox - war - - lightadmin-sandbox - - - - - - ${container.port} - - - - ${basedir}/src/test/jetty8x/jetty-logging.xml - etc - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - - + + + + 4.0.0 + + + org.lightadmin + lightadmin-parent + 1.3.1.BUILD-SNAPSHOT + + + lightadmin-tests + 1.3.1.BUILD-SNAPSHOT + + LightAdmin Selenium + + + 8080 + + 2.45.0 + 1.4.01 + + + + + org.lightadmin + lightadmin-sandbox + ${project.version} + war + + + org.lightadmin + lightadmin-sandbox + ${project.version} + classes + + + + org.seleniumhq.selenium + selenium-java + ${selenium-java.version} + + + + xml-apis + xml-apis + ${xml-apis.version} + + + + com.google.guava + guava + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + runtime + + + + org.springframework + spring-core + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + + + + javax.servlet.jsp + javax.servlet.jsp-api + + + + org.springframework + spring-test + + + junit + junit + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.12 + + + integration-test + integration-test + + integration-test + + + + **/*.class + + true + + + + verify + verify + + verify + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + true + + + + + + + + + test-mode + + + mode + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + dev-mode + + + mode + dev + + + + + + org.codehaus.cargo + cargo-maven2-plugin + 1.2.4 + + + start-cargo + pre-integration-test + + start + + + + stop-cargo + post-integration-test + + stop + + + + + + jetty8x + + org.eclipse.jetty + jetty-distribution + 8.1.8.v20121106 + + + + + ${project.groupId} + lightadmin-sandbox + war + + lightadmin-sandbox + + + + + + ${container.port} + + + + ${basedir}/src/test/jetty8x/jetty-logging.xml + etc + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + diff --git a/pom.xml b/pom.xml index 0f43fefa..6ff0fff3 100644 --- a/pom.xml +++ b/pom.xml @@ -1,70 +1,70 @@ - - - 4.0.0 - org.lightadmin - lightadmin-parent - 1.2.0.BUILD-SNAPSHOT - pom - - LightAdmin Dev Kit - - - UTF-8 - UTF-8 - - 1.7 - 1.7 - - 1.1.2.RELEASE - 1.2 - - 1.0.0.BUILD-SNAPSHOT - - - - - - io.spring.platform - platform-bom - ${spring.platform.version} - pom - import - - - - org.lightadmin - lightadmin - ${project.version} - - - org.lightadmin - light-logging-configurer - ${light-logging-configurer.version} - - - - org.glassfish.web - jstl-impl - ${jstl.version} - - - javax.servlet - servlet-api - - - javax.servlet.jsp - jsp-api - - - - - - - - lightadmin-core - lightadmin-sandbox - lightadmin-tests - - + + + 4.0.0 + org.lightadmin + lightadmin-parent + 1.3.1.BUILD-SNAPSHOT + pom + + LightAdmin Dev Kit + + + UTF-8 + UTF-8 + + 1.7 + 1.7 + + 2.0.8.RELEASE + 1.2 + + 1.0.0.BUILD-SNAPSHOT + + + + + + io.spring.platform + platform-bom + ${spring.platform.version} + pom + import + + + + org.lightadmin + lightadmin + ${project.version} + + + org.lightadmin + light-logging-configurer + ${light-logging-configurer.version} + + + + org.glassfish.web + jstl-impl + ${jstl.version} + + + javax.servlet + servlet-api + + + javax.servlet.jsp + jsp-api + + + + + + + + lightadmin-core + lightadmin-sandbox + lightadmin-tests + + \ No newline at end of file From a198294b4a6ead753cc342959d30576a35c1b469 Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 15:05:43 -0500 Subject: [PATCH 06/18] Admin logo set for CE. --- lightadmin-core/pom.xml | 15 ++++++++++++++- .../images/lightadmin-custom-logo.png | Bin 0 -> 12341 bytes lightadmin-sandbox/pom.xml | 4 ++-- lightadmin-tests/pom.xml | 4 ++-- pom.xml | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 lightadmin-core/src/main/resources/META-INF/resources/lightadmin/images/lightadmin-custom-logo.png diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 9aa8a28c..195166b0 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.2.0.BUILD-SNAPSHOT + 1.2.1.CE-BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner @@ -502,6 +502,19 @@ + + vantage-distribution + + + third-party-snapshots + http://maven2.vantage.com:8080/repo/content/repositories/third-party-snapshots + + + third-party + http://maven2.vantage.com:8080/repo/content/repositories/third-party + + + oss-distribution diff --git a/lightadmin-core/src/main/resources/META-INF/resources/lightadmin/images/lightadmin-custom-logo.png b/lightadmin-core/src/main/resources/META-INF/resources/lightadmin/images/lightadmin-custom-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..929c79f40ac0b8a05c5e2d96736731bf11763f81 GIT binary patch literal 12341 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 literal 0 HcmV?d00001 diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 02d28756..491babb1 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.0.BUILD-SNAPSHOT + 1.2.1.CE-BUILD-SNAPSHOT lightadmin-sandbox - 1.2.0.BUILD-SNAPSHOT + 1.2.1.CE-BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 79c30063..5c58f1a9 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -7,11 +7,11 @@ org.lightadmin lightadmin-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.1.CE-BUILD-SNAPSHOT lightadmin-tests - 1.2.0.BUILD-SNAPSHOT + 1.2.1.CE-BUILD-SNAPSHOT LightAdmin Selenium diff --git a/pom.xml b/pom.xml index 0f43fefa..3b0fb7ff 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.lightadmin lightadmin-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.1.CE-BUILD-SNAPSHOT pom LightAdmin Dev Kit From 4587699861e3c0badf1be1322fac7bc90025c75d Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 19:03:25 -0500 Subject: [PATCH 07/18] Bug that custom logo set in the WEB-INF directory of the project was not loading, is fixed. If the logo image is set in the '/WEB-INF/lightadmin//images/lightadmin-custom-logo.png' path of the web project, still the logo was not loading. This issue is fixed. Also from now on the images (under path: '/images/') will be searched and served in the following paths: classpath:/META-INF/resources/images/ classpath:/META-INF/resources/lightadmin --- lightadmin-core/pom.xml | 2 +- .../config/LightAdminWebApplicationInitializer.java | 10 ++++------ lightadmin-sandbox/pom.xml | 4 ++-- lightadmin-tests/pom.xml | 4 ++-- pom.xml | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 9aa8a28c..271723cd 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner 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..221fe391 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 @@ -134,13 +134,11 @@ private void registerLogoResourceServlet(final ServletContext servletContext) { private ResourceServlet logoResourceServlet(ServletContext servletContext) { Resource classPathResource = defaultResourceLoader().getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_CLASSPATH_LOCATION); - if (classPathResource.exists()) { - return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO)); - } - + Resource webResource = servletContextResourceLoader(servletContext).getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); - if (webResource.exists()) { - return concreteResourceServlet(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); + + if (classPathResource.exists() || webResource.exists()) { + return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO)); } return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_DEFAULT_LOGO_LOCATION)); diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 02d28756..3f8833d9 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT lightadmin-sandbox - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 79c30063..005aff5d 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -7,11 +7,11 @@ org.lightadmin lightadmin-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT lightadmin-tests - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT LightAdmin Selenium diff --git a/pom.xml b/pom.xml index 0f43fefa..7e808048 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.lightadmin lightadmin-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT pom LightAdmin Dev Kit From d12fb3d2075e672548f24797a9fddcc82a8bdb34 Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 19:05:37 -0500 Subject: [PATCH 08/18] Revert "Bug that custom logo set in the WEB-INF directory of the project was not loading, is fixed. If the logo image is set in the '/WEB-INF/lightadmin//images/lightadmin-custom-logo.png' path of the web project, still the logo was not loading. This issue is fixed. Also from now on the images (under path: '/images/') will be searched and served in the following paths: classpath:/META-INF/resources/images/ classpath:/META-INF/resources/lightadmin" This reverts commit 4587699861e3c0badf1be1322fac7bc90025c75d. --- lightadmin-core/pom.xml | 2 +- .../config/LightAdminWebApplicationInitializer.java | 10 ++++++---- lightadmin-sandbox/pom.xml | 4 ++-- lightadmin-tests/pom.xml | 4 ++-- pom.xml | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 271723cd..9aa8a28c 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner 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 221fe391..1e097e23 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 @@ -134,13 +134,15 @@ private void registerLogoResourceServlet(final ServletContext servletContext) { private ResourceServlet logoResourceServlet(ServletContext servletContext) { Resource classPathResource = defaultResourceLoader().getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_CLASSPATH_LOCATION); - - Resource webResource = servletContextResourceLoader(servletContext).getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); - - if (classPathResource.exists() || webResource.exists()) { + if (classPathResource.exists()) { return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO)); } + Resource webResource = servletContextResourceLoader(servletContext).getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); + if (webResource.exists()) { + return concreteResourceServlet(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); + } + return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_DEFAULT_LOGO_LOCATION)); } diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 3f8833d9..02d28756 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT lightadmin-sandbox - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 005aff5d..79c30063 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -7,11 +7,11 @@ org.lightadmin lightadmin-parent - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT lightadmin-tests - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT LightAdmin Selenium diff --git a/pom.xml b/pom.xml index 7e808048..0f43fefa 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.lightadmin lightadmin-parent - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT pom LightAdmin Dev Kit From 27e5c8318c039c1841869f7de6ba49a1583f502e Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 19:08:41 -0500 Subject: [PATCH 09/18] Bug that custom logo set in the WEB-INF directory of the project was not loading, is fixed. If the logo image is set in the '/WEB-INF/lightadmin//images/lightadmin-custom-logo.png' path of the web project, still the logo was not loading. This issue is fixed. Also from now on the images (under path: '/images/') will be searched and served in the following paths: classpath:/META-INF/resources/images/ classpath:/META-INF/resources/lightadmin classpath:/META-INF/resources/lightadmin --- lightadmin-core/pom.xml | 2 +- .../LightAdminWebApplicationInitializer.java | 10 +- .../LightAdminContextConfiguration.java | 343 +++++++++--------- lightadmin-sandbox/pom.xml | 4 +- lightadmin-tests/pom.xml | 4 +- pom.xml | 2 +- 6 files changed, 184 insertions(+), 181 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 9aa8a28c..271723cd 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner 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..221fe391 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 @@ -134,13 +134,11 @@ private void registerLogoResourceServlet(final ServletContext servletContext) { private ResourceServlet logoResourceServlet(ServletContext servletContext) { Resource classPathResource = defaultResourceLoader().getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_CLASSPATH_LOCATION); - if (classPathResource.exists()) { - return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO)); - } - + Resource webResource = servletContextResourceLoader(servletContext).getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); - if (webResource.exists()) { - return concreteResourceServlet(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); + + if (classPathResource.exists() || webResource.exists()) { + return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO)); } return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_DEFAULT_LOGO_LOCATION)); diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java index 95dc1b5a..486fd81a 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java @@ -1,170 +1,175 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.context; - -import org.lightadmin.core.config.LightAdminConfiguration; -import org.lightadmin.core.config.StandardLightAdminConfiguration; -import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; -import org.lightadmin.core.storage.FileResourceStorage; -import org.lightadmin.core.storage.LightAdminFileResourceStorage; -import org.lightadmin.core.view.LightAdminSpringTilesInitializer; -import org.lightadmin.core.view.LightAdminTilesView; -import org.lightadmin.core.web.ApplicationController; -import org.lightadmin.core.web.support.FileResourceLoader; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.support.ReloadableResourceBundleMessageSource; -import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResolver; -import org.springframework.validation.Validator; -import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; -import org.springframework.web.context.support.ServletContextResourceLoader; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; -import org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesViewResolver; - -import javax.servlet.ServletContext; -import java.util.Arrays; -import java.util.List; - -import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION; -import static org.springframework.web.servlet.DispatcherServlet.VIEW_RESOLVER_BEAN_NAME; - -@Configuration -@Import({ - LightAdminDataConfiguration.class, - LightAdminDomainConfiguration.class, - LightAdminRemoteConfiguration.class, - LightAdminRepositoryRestMvcConfiguration.class, - LightAdminViewConfiguration.class -}) -@EnableWebMvc -public class LightAdminContextConfiguration extends WebMvcConfigurerAdapter { - - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/styles/**").addResourceLocations("classpath:/META-INF/resources/styles/"); - registry.addResourceHandler("/scripts/**").addResourceLocations("classpath:/META-INF/resources/scripts/"); - registry.addResourceHandler("/images/**").addResourceLocations("classpath:/META-INF/resources/images/", LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION + "/images/").setCachePeriod(31556926); - } - - @Bean - @Autowired - public LightAdminConfiguration lightAdminConfiguration(ServletContext servletContext) { - return new StandardLightAdminConfiguration(servletContext); - } - - @Bean - @Autowired - public ServletContextResourceLoader servletContextResourceLoader(ServletContext servletContext) { - return new ServletContextResourceLoader(servletContext); - } - - @Bean - @Autowired - public FileResourceStorage fileResourceStorage(GlobalAdministrationConfiguration globalAdministrationConfiguration, LightAdminConfiguration lightAdminConfiguration) { - return new LightAdminFileResourceStorage(globalAdministrationConfiguration, lightAdminConfiguration); - } - - @Bean - @Autowired - public FileResourceLoader fileResourceLoader(GlobalAdministrationConfiguration globalAdministrationConfiguration, FileResourceStorage fileResourceStorage) { - return new FileResourceLoader(globalAdministrationConfiguration, fileResourceStorage); - } - - @Bean - public CommonsMultipartResolver multipartResolver() { - return new CommonsMultipartResolver(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void configureHandlerExceptionResolvers(List exceptionResolvers) { - ExceptionHandlerExceptionResolver exceptionHandlerResolver = new ExceptionHandlerExceptionResolver(); - exceptionHandlerResolver.setCustomArgumentResolvers(Arrays.asList(new ServerHttpRequestMethodArgumentResolver())); - exceptionHandlerResolver.afterPropertiesSet(); - - exceptionResolvers.add(exceptionHandlerResolver); - } - - @Override - public Validator getValidator() { - return validator(); - } - - @Bean - public LocalValidatorFactoryBean validator() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.setValidationMessageSource(messageSource()); - validator.afterPropertiesSet(); - return validator; - } - - @Bean - public MessageSource messageSource() { - ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); - messageSource.setBasename("classpath:messages"); - messageSource.setDefaultEncoding("UTF-8"); - messageSource.setCacheSeconds(0); - messageSource.setFallbackToSystemLocale(false); - return messageSource; - } - - @Bean - public ApplicationController applicationController() { - return new ApplicationController(); - } - - @Bean(name = VIEW_RESOLVER_BEAN_NAME) - public ViewResolver viewResolver() { - return new TilesViewResolver() { - @Override - protected Class requiredViewClass() { - return LightAdminTilesView.class; - } - }; - } - - @Bean - public TilesConfigurer tilesConfigurer() { - final String[] definitions = {"classpath*:META-INF/tiles/definitions.xml"}; - - final TilesConfigurer configurer = new TilesConfigurer(); - configurer.setTilesInitializer(lightAdminSpringTilesInitializer(definitions)); - configurer.setDefinitions(definitions); - configurer.setPreparerFactoryClass(SpringBeanPreparerFactory.class); - return configurer; - } - - private LightAdminSpringTilesInitializer lightAdminSpringTilesInitializer(String[] definitions) { - return new LightAdminSpringTilesInitializer(definitions); - } +/* + * Copyright 2012-2014 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.lightadmin.core.config.context; + +import org.lightadmin.core.config.LightAdminConfiguration; +import org.lightadmin.core.config.StandardLightAdminConfiguration; +import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; +import org.lightadmin.core.storage.FileResourceStorage; +import org.lightadmin.core.storage.LightAdminFileResourceStorage; +import org.lightadmin.core.view.LightAdminSpringTilesInitializer; +import org.lightadmin.core.view.LightAdminTilesView; +import org.lightadmin.core.web.ApplicationController; +import org.lightadmin.core.web.support.FileResourceLoader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResolver; +import org.springframework.validation.Validator; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import org.springframework.web.context.support.ServletContextResourceLoader; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; +import org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; +import org.springframework.web.servlet.view.tiles3.TilesViewResolver; + +import javax.servlet.ServletContext; +import java.util.Arrays; +import java.util.List; + +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION; +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_WEB_INF_LOCATION; +import static org.springframework.web.servlet.DispatcherServlet.VIEW_RESOLVER_BEAN_NAME; + +@Configuration +@Import({ + LightAdminDataConfiguration.class, + LightAdminDomainConfiguration.class, + LightAdminRemoteConfiguration.class, + LightAdminRepositoryRestMvcConfiguration.class, + LightAdminViewConfiguration.class +}) +@EnableWebMvc +public class LightAdminContextConfiguration extends WebMvcConfigurerAdapter { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/styles/**").addResourceLocations("classpath:/META-INF/resources/styles/"); + registry.addResourceHandler("/scripts/**").addResourceLocations("classpath:/META-INF/resources/scripts/"); + registry.addResourceHandler("/images/**").addResourceLocations( + "classpath:/META-INF/resources/images/", + LIGHT_ADMIN_CUSTOM_RESOURCE_WEB_INF_LOCATION + "/images/", + LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION + "/images/" + ).setCachePeriod(31556926); + } + + @Bean + @Autowired + public LightAdminConfiguration lightAdminConfiguration(ServletContext servletContext) { + return new StandardLightAdminConfiguration(servletContext); + } + + @Bean + @Autowired + public ServletContextResourceLoader servletContextResourceLoader(ServletContext servletContext) { + return new ServletContextResourceLoader(servletContext); + } + + @Bean + @Autowired + public FileResourceStorage fileResourceStorage(GlobalAdministrationConfiguration globalAdministrationConfiguration, LightAdminConfiguration lightAdminConfiguration) { + return new LightAdminFileResourceStorage(globalAdministrationConfiguration, lightAdminConfiguration); + } + + @Bean + @Autowired + public FileResourceLoader fileResourceLoader(GlobalAdministrationConfiguration globalAdministrationConfiguration, FileResourceStorage fileResourceStorage) { + return new FileResourceLoader(globalAdministrationConfiguration, fileResourceStorage); + } + + @Bean + public CommonsMultipartResolver multipartResolver() { + return new CommonsMultipartResolver(); + } + + @Override + public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Override + public void configureHandlerExceptionResolvers(List exceptionResolvers) { + ExceptionHandlerExceptionResolver exceptionHandlerResolver = new ExceptionHandlerExceptionResolver(); + exceptionHandlerResolver.setCustomArgumentResolvers(Arrays.asList(new ServerHttpRequestMethodArgumentResolver())); + exceptionHandlerResolver.afterPropertiesSet(); + + exceptionResolvers.add(exceptionHandlerResolver); + } + + @Override + public Validator getValidator() { + return validator(); + } + + @Bean + public LocalValidatorFactoryBean validator() { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.setValidationMessageSource(messageSource()); + validator.afterPropertiesSet(); + return validator; + } + + @Bean + public MessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setBasename("classpath:messages"); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setCacheSeconds(0); + messageSource.setFallbackToSystemLocale(false); + return messageSource; + } + + @Bean + public ApplicationController applicationController() { + return new ApplicationController(); + } + + @Bean(name = VIEW_RESOLVER_BEAN_NAME) + public ViewResolver viewResolver() { + return new TilesViewResolver() { + @Override + protected Class requiredViewClass() { + return LightAdminTilesView.class; + } + }; + } + + @Bean + public TilesConfigurer tilesConfigurer() { + final String[] definitions = {"classpath*:META-INF/tiles/definitions.xml"}; + + final TilesConfigurer configurer = new TilesConfigurer(); + configurer.setTilesInitializer(lightAdminSpringTilesInitializer(definitions)); + configurer.setDefinitions(definitions); + configurer.setPreparerFactoryClass(SpringBeanPreparerFactory.class); + return configurer; + } + + private LightAdminSpringTilesInitializer lightAdminSpringTilesInitializer(String[] definitions) { + return new LightAdminSpringTilesInitializer(definitions); + } } \ No newline at end of file diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 02d28756..3f8833d9 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT lightadmin-sandbox - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 79c30063..005aff5d 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -7,11 +7,11 @@ org.lightadmin lightadmin-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT lightadmin-tests - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT LightAdmin Selenium diff --git a/pom.xml b/pom.xml index 0f43fefa..7e808048 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.lightadmin lightadmin-parent - 1.2.0.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT pom LightAdmin Dev Kit From 94993cbd5df0d150cb7ff7a64f0d6eaf4cc14db9 Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 22 Feb 2018 19:20:10 -0500 Subject: [PATCH 10/18] Custom Logo Image can now be served from the WEB-INF directory, so no need to serve from the LightAdmin jar. --- .../images/lightadmin-custom-logo.png | Bin 12341 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lightadmin-core/src/main/resources/META-INF/resources/lightadmin/images/lightadmin-custom-logo.png diff --git a/lightadmin-core/src/main/resources/META-INF/resources/lightadmin/images/lightadmin-custom-logo.png b/lightadmin-core/src/main/resources/META-INF/resources/lightadmin/images/lightadmin-custom-logo.png deleted file mode 100644 index 929c79f40ac0b8a05c5e2d96736731bf11763f81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12341 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 From dca8bb010a40e780deac71b5922a2fbc0df56492 Mon Sep 17 00:00:00 2001 From: grahman Date: Fri, 23 Feb 2018 10:28:11 -0500 Subject: [PATCH 11/18] Revert "Bug that custom logo set in the WEB-INF directory of the project was not loading, is fixed. If the logo image is set in the '/WEB-INF/lightadmin//images/lightadmin-custom-logo.png' path of the web project, still the logo was not loading. This issue is fixed. Also from now on the images (under path: '/images/') will be searched and served in the following paths: classpath:/META-INF/resources/images/ classpath:/META-INF/resources/lightadmin classpath:/META-INF/resources/lightadmin" This reverts commit 27e5c8318c039c1841869f7de6ba49a1583f502e. --- lightadmin-core/pom.xml | 2 +- .../LightAdminWebApplicationInitializer.java | 10 +- .../LightAdminContextConfiguration.java | 343 +++++++++--------- lightadmin-sandbox/pom.xml | 4 +- lightadmin-tests/pom.xml | 4 +- pom.xml | 2 +- 6 files changed, 181 insertions(+), 184 deletions(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 271723cd..9aa8a28c 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -8,7 +8,7 @@ lightadmin jar - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT LightAdmin Pluggable data management solution for Java web applications developed in a "Rapid" manner 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 221fe391..1e097e23 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 @@ -134,13 +134,15 @@ private void registerLogoResourceServlet(final ServletContext servletContext) { private ResourceServlet logoResourceServlet(ServletContext servletContext) { Resource classPathResource = defaultResourceLoader().getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_CLASSPATH_LOCATION); - - Resource webResource = servletContextResourceLoader(servletContext).getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); - - if (classPathResource.exists() || webResource.exists()) { + if (classPathResource.exists()) { return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO)); } + Resource webResource = servletContextResourceLoader(servletContext).getResource(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); + if (webResource.exists()) { + return concreteResourceServlet(LIGHT_ADMIN_CUSTOM_RESOURCE_LOGO_WEB_INF_LOCATION); + } + return concreteResourceServlet(resourceServletMapping(servletContext, LIGHT_ADMIN_DEFAULT_LOGO_LOCATION)); } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java index 486fd81a..95dc1b5a 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminContextConfiguration.java @@ -1,175 +1,170 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.context; - -import org.lightadmin.core.config.LightAdminConfiguration; -import org.lightadmin.core.config.StandardLightAdminConfiguration; -import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; -import org.lightadmin.core.storage.FileResourceStorage; -import org.lightadmin.core.storage.LightAdminFileResourceStorage; -import org.lightadmin.core.view.LightAdminSpringTilesInitializer; -import org.lightadmin.core.view.LightAdminTilesView; -import org.lightadmin.core.web.ApplicationController; -import org.lightadmin.core.web.support.FileResourceLoader; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.support.ReloadableResourceBundleMessageSource; -import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResolver; -import org.springframework.validation.Validator; -import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; -import org.springframework.web.context.support.ServletContextResourceLoader; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; -import org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesViewResolver; - -import javax.servlet.ServletContext; -import java.util.Arrays; -import java.util.List; - -import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION; -import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_WEB_INF_LOCATION; -import static org.springframework.web.servlet.DispatcherServlet.VIEW_RESOLVER_BEAN_NAME; - -@Configuration -@Import({ - LightAdminDataConfiguration.class, - LightAdminDomainConfiguration.class, - LightAdminRemoteConfiguration.class, - LightAdminRepositoryRestMvcConfiguration.class, - LightAdminViewConfiguration.class -}) -@EnableWebMvc -public class LightAdminContextConfiguration extends WebMvcConfigurerAdapter { - - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/styles/**").addResourceLocations("classpath:/META-INF/resources/styles/"); - registry.addResourceHandler("/scripts/**").addResourceLocations("classpath:/META-INF/resources/scripts/"); - registry.addResourceHandler("/images/**").addResourceLocations( - "classpath:/META-INF/resources/images/", - LIGHT_ADMIN_CUSTOM_RESOURCE_WEB_INF_LOCATION + "/images/", - LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION + "/images/" - ).setCachePeriod(31556926); - } - - @Bean - @Autowired - public LightAdminConfiguration lightAdminConfiguration(ServletContext servletContext) { - return new StandardLightAdminConfiguration(servletContext); - } - - @Bean - @Autowired - public ServletContextResourceLoader servletContextResourceLoader(ServletContext servletContext) { - return new ServletContextResourceLoader(servletContext); - } - - @Bean - @Autowired - public FileResourceStorage fileResourceStorage(GlobalAdministrationConfiguration globalAdministrationConfiguration, LightAdminConfiguration lightAdminConfiguration) { - return new LightAdminFileResourceStorage(globalAdministrationConfiguration, lightAdminConfiguration); - } - - @Bean - @Autowired - public FileResourceLoader fileResourceLoader(GlobalAdministrationConfiguration globalAdministrationConfiguration, FileResourceStorage fileResourceStorage) { - return new FileResourceLoader(globalAdministrationConfiguration, fileResourceStorage); - } - - @Bean - public CommonsMultipartResolver multipartResolver() { - return new CommonsMultipartResolver(); - } - - @Override - public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } - - @Override - public void configureHandlerExceptionResolvers(List exceptionResolvers) { - ExceptionHandlerExceptionResolver exceptionHandlerResolver = new ExceptionHandlerExceptionResolver(); - exceptionHandlerResolver.setCustomArgumentResolvers(Arrays.asList(new ServerHttpRequestMethodArgumentResolver())); - exceptionHandlerResolver.afterPropertiesSet(); - - exceptionResolvers.add(exceptionHandlerResolver); - } - - @Override - public Validator getValidator() { - return validator(); - } - - @Bean - public LocalValidatorFactoryBean validator() { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.setValidationMessageSource(messageSource()); - validator.afterPropertiesSet(); - return validator; - } - - @Bean - public MessageSource messageSource() { - ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); - messageSource.setBasename("classpath:messages"); - messageSource.setDefaultEncoding("UTF-8"); - messageSource.setCacheSeconds(0); - messageSource.setFallbackToSystemLocale(false); - return messageSource; - } - - @Bean - public ApplicationController applicationController() { - return new ApplicationController(); - } - - @Bean(name = VIEW_RESOLVER_BEAN_NAME) - public ViewResolver viewResolver() { - return new TilesViewResolver() { - @Override - protected Class requiredViewClass() { - return LightAdminTilesView.class; - } - }; - } - - @Bean - public TilesConfigurer tilesConfigurer() { - final String[] definitions = {"classpath*:META-INF/tiles/definitions.xml"}; - - final TilesConfigurer configurer = new TilesConfigurer(); - configurer.setTilesInitializer(lightAdminSpringTilesInitializer(definitions)); - configurer.setDefinitions(definitions); - configurer.setPreparerFactoryClass(SpringBeanPreparerFactory.class); - return configurer; - } - - private LightAdminSpringTilesInitializer lightAdminSpringTilesInitializer(String[] definitions) { - return new LightAdminSpringTilesInitializer(definitions); - } +/* + * Copyright 2012-2014 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.lightadmin.core.config.context; + +import org.lightadmin.core.config.LightAdminConfiguration; +import org.lightadmin.core.config.StandardLightAdminConfiguration; +import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; +import org.lightadmin.core.storage.FileResourceStorage; +import org.lightadmin.core.storage.LightAdminFileResourceStorage; +import org.lightadmin.core.view.LightAdminSpringTilesInitializer; +import org.lightadmin.core.view.LightAdminTilesView; +import org.lightadmin.core.web.ApplicationController; +import org.lightadmin.core.web.support.FileResourceLoader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.data.rest.webmvc.ServerHttpRequestMethodArgumentResolver; +import org.springframework.validation.Validator; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import org.springframework.web.context.support.ServletContextResourceLoader; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; +import org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; +import org.springframework.web.servlet.view.tiles3.TilesViewResolver; + +import javax.servlet.ServletContext; +import java.util.Arrays; +import java.util.List; + +import static org.lightadmin.core.util.LightAdminConfigurationUtils.LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION; +import static org.springframework.web.servlet.DispatcherServlet.VIEW_RESOLVER_BEAN_NAME; + +@Configuration +@Import({ + LightAdminDataConfiguration.class, + LightAdminDomainConfiguration.class, + LightAdminRemoteConfiguration.class, + LightAdminRepositoryRestMvcConfiguration.class, + LightAdminViewConfiguration.class +}) +@EnableWebMvc +public class LightAdminContextConfiguration extends WebMvcConfigurerAdapter { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/styles/**").addResourceLocations("classpath:/META-INF/resources/styles/"); + registry.addResourceHandler("/scripts/**").addResourceLocations("classpath:/META-INF/resources/scripts/"); + registry.addResourceHandler("/images/**").addResourceLocations("classpath:/META-INF/resources/images/", LIGHT_ADMIN_CUSTOM_RESOURCE_CLASSPATH_LOCATION + "/images/").setCachePeriod(31556926); + } + + @Bean + @Autowired + public LightAdminConfiguration lightAdminConfiguration(ServletContext servletContext) { + return new StandardLightAdminConfiguration(servletContext); + } + + @Bean + @Autowired + public ServletContextResourceLoader servletContextResourceLoader(ServletContext servletContext) { + return new ServletContextResourceLoader(servletContext); + } + + @Bean + @Autowired + public FileResourceStorage fileResourceStorage(GlobalAdministrationConfiguration globalAdministrationConfiguration, LightAdminConfiguration lightAdminConfiguration) { + return new LightAdminFileResourceStorage(globalAdministrationConfiguration, lightAdminConfiguration); + } + + @Bean + @Autowired + public FileResourceLoader fileResourceLoader(GlobalAdministrationConfiguration globalAdministrationConfiguration, FileResourceStorage fileResourceStorage) { + return new FileResourceLoader(globalAdministrationConfiguration, fileResourceStorage); + } + + @Bean + public CommonsMultipartResolver multipartResolver() { + return new CommonsMultipartResolver(); + } + + @Override + public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Override + public void configureHandlerExceptionResolvers(List exceptionResolvers) { + ExceptionHandlerExceptionResolver exceptionHandlerResolver = new ExceptionHandlerExceptionResolver(); + exceptionHandlerResolver.setCustomArgumentResolvers(Arrays.asList(new ServerHttpRequestMethodArgumentResolver())); + exceptionHandlerResolver.afterPropertiesSet(); + + exceptionResolvers.add(exceptionHandlerResolver); + } + + @Override + public Validator getValidator() { + return validator(); + } + + @Bean + public LocalValidatorFactoryBean validator() { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.setValidationMessageSource(messageSource()); + validator.afterPropertiesSet(); + return validator; + } + + @Bean + public MessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setBasename("classpath:messages"); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setCacheSeconds(0); + messageSource.setFallbackToSystemLocale(false); + return messageSource; + } + + @Bean + public ApplicationController applicationController() { + return new ApplicationController(); + } + + @Bean(name = VIEW_RESOLVER_BEAN_NAME) + public ViewResolver viewResolver() { + return new TilesViewResolver() { + @Override + protected Class requiredViewClass() { + return LightAdminTilesView.class; + } + }; + } + + @Bean + public TilesConfigurer tilesConfigurer() { + final String[] definitions = {"classpath*:META-INF/tiles/definitions.xml"}; + + final TilesConfigurer configurer = new TilesConfigurer(); + configurer.setTilesInitializer(lightAdminSpringTilesInitializer(definitions)); + configurer.setDefinitions(definitions); + configurer.setPreparerFactoryClass(SpringBeanPreparerFactory.class); + return configurer; + } + + private LightAdminSpringTilesInitializer lightAdminSpringTilesInitializer(String[] definitions) { + return new LightAdminSpringTilesInitializer(definitions); + } } \ No newline at end of file diff --git a/lightadmin-sandbox/pom.xml b/lightadmin-sandbox/pom.xml index 3f8833d9..02d28756 100644 --- a/lightadmin-sandbox/pom.xml +++ b/lightadmin-sandbox/pom.xml @@ -7,11 +7,11 @@ lightadmin-parent org.lightadmin - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT lightadmin-sandbox - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT war LightAdmin SandBox diff --git a/lightadmin-tests/pom.xml b/lightadmin-tests/pom.xml index 005aff5d..79c30063 100644 --- a/lightadmin-tests/pom.xml +++ b/lightadmin-tests/pom.xml @@ -7,11 +7,11 @@ org.lightadmin lightadmin-parent - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT lightadmin-tests - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT LightAdmin Selenium diff --git a/pom.xml b/pom.xml index 7e808048..0f43fefa 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.lightadmin lightadmin-parent - 1.2.1.BUILD-SNAPSHOT + 1.2.0.BUILD-SNAPSHOT pom LightAdmin Dev Kit From 65cd213d0e92edeab9d4effa06d4b0b7cd67e37e Mon Sep 17 00:00:00 2001 From: grahman Date: Wed, 7 Mar 2018 15:22:54 -0500 Subject: [PATCH 12/18] Spring Platform upgraded to Brussels-SR6 --- lightadmin-core/pom.xml | 2 +- ...inBeanDefinitionRegistryPostProcessor.java | 427 ++++++------ .../LightAdminRepositoryRestConfigurer.java | 73 +++ ...htAdminRepositoryRestMvcConfiguration.java | 45 +- .../unit/DomainConfigurationUnitType.java | 5 - ...amicPersistentEntityResourceAssembler.java | 46 +- ...amicPersistentEntityResourceProcessor.java | 611 +++++++++--------- 7 files changed, 627 insertions(+), 582 deletions(-) create mode 100644 lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index db2297a6..b0fb1570 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -94,7 +94,7 @@ 1.7 1.7 - 2.0.8.RELEASE + Brussels-SR6 4.0 4.2 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..de4673cd 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 @@ -1,214 +1,215 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.config.bootstrap; - -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; -import org.lightadmin.core.config.domain.DomainTypeAdministrationConfigurationFactory; -import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; -import org.lightadmin.core.config.domain.unit.ConfigurationUnits; -import org.lightadmin.core.persistence.repository.DynamicRepositoryClassFactory; -import org.lightadmin.core.persistence.repository.JavassistDynamicJpaRepositoryClassFactory; -import org.lightadmin.core.util.DynamicRepositoryBeanNameGenerator; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -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.rest.core.event.AbstractRepositoryEventListener; -import org.springframework.orm.jpa.EntityManagerFactoryUtils; -import org.springframework.orm.jpa.SharedEntityManagerCreator; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.ServletContextResourceLoader; -import org.springframework.web.context.support.WebApplicationContextUtils; - -import javax.persistence.EntityManager; -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; -import static com.google.common.collect.Sets.newLinkedHashSet; -import static org.lightadmin.core.config.domain.unit.ConfigurationUnitsConverter.unitsFromAutowiredConfiguration; -import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition; -import static org.springframework.util.StringUtils.tokenizeToStringArray; - -public class LightAdminBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { - - public static final String JPA_MAPPPING_CONTEXT_BEAN = "jpaMapppingContext"; - public static final String REPOSITORIES_BEAN = "repositories"; - public static final String LIGHTADMIN_CONFIGURATION_BEAN = "lightAdminConfiguration"; - public static final String CONFIGURATION_UNITS_VALIDATOR_BEAN = "configurationUnitsValidator"; - - protected static final String CONFIG_LOCATION_DELIMITERS = ",; \t\n"; - - protected DynamicRepositoryBeanNameGenerator nameGenerator = new DynamicRepositoryBeanNameGenerator(); - protected DynamicRepositoryClassFactory classFactory = new JavassistDynamicJpaRepositoryClassFactory(nameGenerator); - protected ClassScanner classScanner = new AdministrationClassScanner(); - - protected ServletContext servletContext; - - protected String basePackage; - - public LightAdminBeanDefinitionRegistryPostProcessor(String basePackage, ServletContext servletContext) { - this.servletContext = servletContext; - this.basePackage = basePackage; - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - WebApplicationContext rootContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); - - EntityManager entityManager = findEntityManager(rootContext); - - ResourceLoader resourceLoader = newResourceLoader(servletContext); - - Set administrationConfigs = scanPackageForAdministrationClasses(); - - Set configurationUnits = configurationUnits(rootContext, administrationConfigs); - - registry.registerBeanDefinition(JPA_MAPPPING_CONTEXT_BEAN, mappingContext(entityManager)); - - registry.registerBeanDefinition(CONFIGURATION_UNITS_VALIDATOR_BEAN, configurationUnitsValidator(resourceLoader)); - - for (Class managedEntityType : managedEntities(entityManager)) { - Class repoInterface = createDynamicRepositoryClass(managedEntityType, entityManager); - registry.registerBeanDefinition(beanName(repoInterface), repositoryFactory(repoInterface, entityManager)); - } - - registerRepositoryEventListeners(configurationUnits, registry); - - registry.registerBeanDefinition(beanName(GlobalAdministrationConfiguration.class), globalAdministrationConfigurationFactoryBeanDefinition(configurationUnits)); - registry.registerBeanDefinition(beanName(DomainTypeAdministrationConfigurationFactory.class), domainTypeAdministrationConfigurationFactoryDefinition(entityManager)); - } - - private void registerRepositoryEventListeners(Set configurationUnits, BeanDefinitionRegistry registry) { - for (ConfigurationUnits configurationUnit : configurationUnits) { - Class repositoryEventListenerClass = configurationUnit.getEntityConfiguration().getRepositoryEventListener(); - if (repositoryEventListenerClass != null) { - registry.registerBeanDefinition(beanName(repositoryEventListenerClass), repositoryEventListener(repositoryEventListenerClass)); - } - } - } - - private Set configurationUnits(WebApplicationContext rootContext, Set administrationConfigs) { - Set configurationUnitsCollection = newLinkedHashSet(); - for (Class administrationConfig : administrationConfigs) { - ConfigurationUnits configurationUnits = unitsFromAutowiredConfiguration(administrationConfig, rootContext.getAutowireCapableBeanFactory()); - configurationUnitsCollection.add(configurationUnits); - } - return configurationUnitsCollection; - } - - private Iterable> managedEntities(EntityManager entityManager) { - Set> managedEntities = newHashSet(); - for (EntityType entity : entityManager.getMetamodel().getEntities()) { - if (entity.getJavaType() != null) - managedEntities.add(entity.getJavaType()); - } - return managedEntities; - } - - private BeanDefinition repositoryEventListener(Class repositoryEventListener) { - BeanDefinitionBuilder builder = rootBeanDefinition(repositoryEventListener); - builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT); - return builder.getBeanDefinition(); - } - - private BeanDefinition configurationUnitsValidator(ResourceLoader resourceLoader) { - BeanDefinitionBuilder builder = rootBeanDefinition(CompositeConfigurationUnitsValidator.class); - builder.addConstructorArgReference(JPA_MAPPPING_CONTEXT_BEAN); - builder.addConstructorArgValue(resourceLoader); - builder.addConstructorArgReference(LIGHTADMIN_CONFIGURATION_BEAN); - return builder.getBeanDefinition(); - } - - private BeanDefinition mappingContext(EntityManager entityManager) { - BeanDefinitionBuilder builder = rootBeanDefinition(JpaMetamodelMappingContextFactoryBean.class); - builder.addPropertyValue("entityManager", entityManager); - return builder.getBeanDefinition(); - } - - private BeanDefinition globalAdministrationConfigurationFactoryBeanDefinition(Set configurationUnits) { - BeanDefinitionBuilder builder = rootBeanDefinition(GlobalAdministrationConfigurationFactoryBean.class); - builder.addPropertyReference("domainTypeAdministrationConfigurationFactory", beanName(DomainTypeAdministrationConfigurationFactory.class)); - builder.addPropertyValue("domainTypeConfigurationUnits", configurationUnits); - builder.addPropertyReference("mappingContext", JPA_MAPPPING_CONTEXT_BEAN); - builder.addPropertyReference("repositories", REPOSITORIES_BEAN); - builder.addPropertyReference("configurationUnitsValidator", CONFIGURATION_UNITS_VALIDATOR_BEAN); - return builder.getBeanDefinition(); - } - - private BeanDefinition repositoryFactory(Class repoInterface, EntityManager entityManager) { - BeanDefinitionBuilder builder = rootBeanDefinition(JpaRepositoryFactoryBean.class); - builder.addPropertyValue("entityManager", entityManager); - builder.addPropertyReference("mappingContext", JPA_MAPPPING_CONTEXT_BEAN); - builder.addPropertyValue("repositoryInterface", repoInterface); - return builder.getBeanDefinition(); - } - - private BeanDefinition domainTypeAdministrationConfigurationFactoryDefinition(EntityManager entityManager) { - BeanDefinitionBuilder builder = rootBeanDefinition(DomainTypeAdministrationConfigurationFactory.class); - builder.addConstructorArgReference(REPOSITORIES_BEAN); - builder.addConstructorArgValue(entityManager); - builder.addConstructorArgReference(JPA_MAPPPING_CONTEXT_BEAN); - return builder.getBeanDefinition(); - } - - private EntityManager findEntityManager(WebApplicationContext rootContext) { - EntityManagerFactory entityManagerFactory = EntityManagerFactoryUtils.findEntityManagerFactory(rootContext, null); - - return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory); - } - - private ServletContextResourceLoader newResourceLoader(ServletContext servletContext) { - return new ServletContextResourceLoader(servletContext); - } - - private Class createDynamicRepositoryClass(Class domainType, EntityManager entityManager) { - EntityType entityType = entityManager.getMetamodel().entity(domainType); - Class idType = entityType.getIdType().getJavaType(); - - return classFactory.createDynamicRepositoryClass(domainType, idType); - } - - private Set scanPackageForAdministrationClasses() { - final Set administrationConfigs = newLinkedHashSet(); - for (String configurationsBasePackage : configurationsBasePackages()) { - administrationConfigs.addAll(classScanner.scan(configurationsBasePackage)); - } - - return administrationConfigs; - } - - private String[] configurationsBasePackages() { - return tokenizeToStringArray(basePackage, CONFIG_LOCATION_DELIMITERS); - } - - private String beanName(Class type) { - return nameGenerator.generateBeanNameDecapitalized(type); - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { - } +/* + * Copyright 2012-2014 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.lightadmin.core.config.bootstrap; + +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; +import org.lightadmin.core.config.domain.DomainTypeAdministrationConfigurationFactory; +import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; +import org.lightadmin.core.config.domain.unit.ConfigurationUnits; +import org.lightadmin.core.persistence.repository.DynamicRepositoryClassFactory; +import org.lightadmin.core.persistence.repository.JavassistDynamicJpaRepositoryClassFactory; +import org.lightadmin.core.util.DynamicRepositoryBeanNameGenerator; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +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.rest.core.event.AbstractRepositoryEventListener; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; +import org.springframework.orm.jpa.SharedEntityManagerCreator; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.ServletContextResourceLoader; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import javax.persistence.EntityManager; +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; +import static com.google.common.collect.Sets.newLinkedHashSet; +import static org.lightadmin.core.config.domain.unit.ConfigurationUnitsConverter.unitsFromAutowiredConfiguration; +import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition; +import static org.springframework.util.StringUtils.tokenizeToStringArray; + +public class LightAdminBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { + + public static final String JPA_MAPPPING_CONTEXT_BEAN = "jpaMapppingContext"; + public static final String REPOSITORIES_BEAN = "repositories"; + public static final String LIGHTADMIN_CONFIGURATION_BEAN = "lightAdminConfiguration"; + public static final String CONFIGURATION_UNITS_VALIDATOR_BEAN = "configurationUnitsValidator"; + + protected static final String CONFIG_LOCATION_DELIMITERS = ",; \t\n"; + + protected DynamicRepositoryBeanNameGenerator nameGenerator = new DynamicRepositoryBeanNameGenerator(); + protected DynamicRepositoryClassFactory classFactory = new JavassistDynamicJpaRepositoryClassFactory(nameGenerator); + protected ClassScanner classScanner = new AdministrationClassScanner(); + + protected ServletContext servletContext; + + protected String basePackage; + + public LightAdminBeanDefinitionRegistryPostProcessor(String basePackage, ServletContext servletContext) { + this.servletContext = servletContext; + this.basePackage = basePackage; + } + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + WebApplicationContext rootContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); + + EntityManager entityManager = findEntityManager(rootContext); + + ResourceLoader resourceLoader = newResourceLoader(servletContext); + + Set administrationConfigs = scanPackageForAdministrationClasses(); + + Set configurationUnits = configurationUnits(rootContext, administrationConfigs); + + registry.registerBeanDefinition(JPA_MAPPPING_CONTEXT_BEAN, mappingContext(entityManager)); + + registry.registerBeanDefinition(CONFIGURATION_UNITS_VALIDATOR_BEAN, configurationUnitsValidator(resourceLoader)); + + for (Class managedEntityType : managedEntities(entityManager)) { + Class repoInterface = createDynamicRepositoryClass(managedEntityType, entityManager); + registry.registerBeanDefinition(beanName(repoInterface), repositoryFactory(repoInterface, entityManager)); + } + + registerRepositoryEventListeners(configurationUnits, registry); + + registry.registerBeanDefinition(beanName(GlobalAdministrationConfiguration.class), globalAdministrationConfigurationFactoryBeanDefinition(configurationUnits)); + registry.registerBeanDefinition(beanName(DomainTypeAdministrationConfigurationFactory.class), domainTypeAdministrationConfigurationFactoryDefinition(entityManager)); + } + + private void registerRepositoryEventListeners(Set configurationUnits, BeanDefinitionRegistry registry) { + for (ConfigurationUnits configurationUnit : configurationUnits) { + Class repositoryEventListenerClass = configurationUnit.getEntityConfiguration().getRepositoryEventListener(); + if (repositoryEventListenerClass != null) { + registry.registerBeanDefinition(beanName(repositoryEventListenerClass), repositoryEventListener(repositoryEventListenerClass)); + } + } + } + + private Set configurationUnits(WebApplicationContext rootContext, Set administrationConfigs) { + Set configurationUnitsCollection = newLinkedHashSet(); + for (Class administrationConfig : administrationConfigs) { + ConfigurationUnits configurationUnits = unitsFromAutowiredConfiguration(administrationConfig, rootContext.getAutowireCapableBeanFactory()); + configurationUnitsCollection.add(configurationUnits); + } + return configurationUnitsCollection; + } + + private Iterable> managedEntities(EntityManager entityManager) { + Set> managedEntities = newHashSet(); + for (EntityType entity : entityManager.getMetamodel().getEntities()) { + if (entity.getJavaType() != null) + managedEntities.add(entity.getJavaType()); + } + return managedEntities; + } + + private BeanDefinition repositoryEventListener(Class repositoryEventListener) { + BeanDefinitionBuilder builder = rootBeanDefinition(repositoryEventListener); + builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_AUTODETECT); + return builder.getBeanDefinition(); + } + + private BeanDefinition configurationUnitsValidator(ResourceLoader resourceLoader) { + BeanDefinitionBuilder builder = rootBeanDefinition(CompositeConfigurationUnitsValidator.class); + builder.addConstructorArgReference(JPA_MAPPPING_CONTEXT_BEAN); + builder.addConstructorArgValue(resourceLoader); + builder.addConstructorArgReference(LIGHTADMIN_CONFIGURATION_BEAN); + return builder.getBeanDefinition(); + } + + private BeanDefinition mappingContext(EntityManager entityManager) { + BeanDefinitionBuilder builder = rootBeanDefinition(JpaMetamodelMappingContextFactoryBean.class); + builder.addPropertyValue("entityManager", entityManager); + return builder.getBeanDefinition(); + } + + private BeanDefinition globalAdministrationConfigurationFactoryBeanDefinition(Set configurationUnits) { + BeanDefinitionBuilder builder = rootBeanDefinition(GlobalAdministrationConfigurationFactoryBean.class); + builder.addPropertyReference("domainTypeAdministrationConfigurationFactory", beanName(DomainTypeAdministrationConfigurationFactory.class)); + builder.addPropertyValue("domainTypeConfigurationUnits", configurationUnits); + builder.addPropertyReference("mappingContext", JPA_MAPPPING_CONTEXT_BEAN); + builder.addPropertyReference("repositories", REPOSITORIES_BEAN); + builder.addPropertyReference("configurationUnitsValidator", CONFIGURATION_UNITS_VALIDATOR_BEAN); + return builder.getBeanDefinition(); + } + + private BeanDefinition repositoryFactory(Class repoInterface, EntityManager entityManager) { + BeanDefinitionBuilder builder = rootBeanDefinition(JpaRepositoryFactoryBean.class); + builder.addConstructorArgValue(repoInterface); + builder.addPropertyValue("entityManager", entityManager); + builder.addPropertyReference("mappingContext", JPA_MAPPPING_CONTEXT_BEAN); + return builder.getBeanDefinition(); + } + + private BeanDefinition domainTypeAdministrationConfigurationFactoryDefinition(EntityManager entityManager) { + BeanDefinitionBuilder builder = rootBeanDefinition(DomainTypeAdministrationConfigurationFactory.class); + builder.addConstructorArgReference(REPOSITORIES_BEAN); + builder.addConstructorArgValue(entityManager); + builder.addConstructorArgReference(JPA_MAPPPING_CONTEXT_BEAN); + return builder.getBeanDefinition(); + } + + private EntityManager findEntityManager(WebApplicationContext rootContext) { + EntityManagerFactory entityManagerFactory = EntityManagerFactoryUtils.findEntityManagerFactory(rootContext, null); + + return SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory); + } + + private ServletContextResourceLoader newResourceLoader(ServletContext servletContext) { + return new ServletContextResourceLoader(servletContext); + } + + @SuppressWarnings("unchecked") + private Class createDynamicRepositoryClass(Class domainType, EntityManager entityManager) { + EntityType entityType = entityManager.getMetamodel().entity(domainType); + Class idType = entityType.getIdType().getJavaType(); + + return classFactory.createDynamicRepositoryClass(domainType, idType); + } + + private Set scanPackageForAdministrationClasses() { + final Set administrationConfigs = newLinkedHashSet(); + for (String configurationsBasePackage : configurationsBasePackages()) { + administrationConfigs.addAll(classScanner.scan(configurationsBasePackage)); + } + + return administrationConfigs; + } + + private String[] configurationsBasePackages() { + return tokenizeToStringArray(basePackage, CONFIG_LOCATION_DELIMITERS); + } + + private String beanName(Class type) { + return nameGenerator.generateBeanNameDecapitalized(type); + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java new file mode 100644 index 00000000..c8ce59de --- /dev/null +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java @@ -0,0 +1,73 @@ +/** + * + */ +package org.lightadmin.core.config.context; + +import org.lightadmin.core.config.LightAdminConfiguration; +import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; +import org.lightadmin.core.web.json.LightAdminJacksonModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; +import org.springframework.validation.Validator; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * @author Gazi Rahman + * + */ +@Configuration +public class LightAdminRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter + implements RepositoryRestConfigurer { + private static Logger logger = LoggerFactory.getLogger(LightAdminRepositoryRestConfigurer.class); + + @Autowired + private ListableBeanFactory beanFactory; + + /** + * + */ + public LightAdminRepositoryRestConfigurer() { + logger.debug("LightAdminRepositoryRestConfigurer instantiated"); + } + + @Override + public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { + config.setDefaultPageSize(10); + config.setBasePath(lightAdminConfiguration().getApplicationRestBasePath()); + config.exposeIdsFor(globalAdministrationConfiguration().getAllDomainTypesAsArray()); + config.setReturnBodyOnCreate(true); + config.setReturnBodyOnUpdate(true); + } + + @Override + public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { + validatingListener.addValidator("beforeCreate", validator()); + validatingListener.addValidator("beforeSave", validator()); + } + + @Override + public void configureJacksonObjectMapper(ObjectMapper objectMapper) { + objectMapper.registerModule(new LightAdminJacksonModule(globalAdministrationConfiguration())); + } + + private GlobalAdministrationConfiguration globalAdministrationConfiguration() { + return beanFactory.getBean(GlobalAdministrationConfiguration.class); + } + + private LightAdminConfiguration lightAdminConfiguration() { + return beanFactory.getBean(LightAdminConfiguration.class); + } + + private Validator validator() { + return beanFactory.getBean("validator", Validator.class); + } + +} 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 58aabc00..3839b5de 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,7 +15,6 @@ */ package org.lightadmin.core.config.context; -import com.fasterxml.jackson.databind.ObjectMapper; import org.lightadmin.core.config.LightAdminConfiguration; import org.lightadmin.core.config.bootstrap.RepositoriesFactoryBean; import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; @@ -24,23 +23,22 @@ import org.lightadmin.core.persistence.support.DynamicDomainObjectMerger; 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.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.ConversionService; import org.springframework.data.repository.support.Repositories; import org.springframework.data.repository.support.RepositoryInvokerFactory; -import org.springframework.data.rest.core.config.RepositoryRestConfiguration; -import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; import org.springframework.data.rest.core.support.DomainObjectMerger; import org.springframework.data.rest.webmvc.RepositoryRestController; import org.springframework.data.rest.webmvc.config.PersistentEntityResourceAssemblerArgumentResolver; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; -import org.springframework.validation.Validator; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; @@ -70,7 +68,9 @@ public DynamicRepositoryEntityLinks dynamicRepositoryEntityLinks() { @Bean public DynamicPersistentEntityResourceProcessor dynamicPersistentEntityResourceProcessor() { - return new DynamicPersistentEntityResourceProcessor(globalAdministrationConfiguration(), fileResourceStorage(), dynamicRepositoryEntityLinks(), domainEntityLinks(), resourceMappings()); + return new DynamicPersistentEntityResourceProcessor(globalAdministrationConfiguration(), + fileResourceStorage(), dynamicRepositoryEntityLinks(), domainEntityLinks(), + resourceMappings(), associationLinks()); } @Bean @@ -92,9 +92,9 @@ public DomainObjectMerger domainObjectMerger() throws Exception { return new DynamicDomainObjectMerger(repositories(), defaultConversionService(), globalAdministrationConfiguration()); } - @Bean - public RepositoryInvokerFactory repositoryInvokerFactory() { - RepositoryInvokerFactory repositoryInvokerFactory = super.repositoryInvokerFactory(); + @Override + public RepositoryInvokerFactory repositoryInvokerFactory(@Qualifier ConversionService defaultConversionService) { + RepositoryInvokerFactory repositoryInvokerFactory = super.repositoryInvokerFactory(defaultConversionService); return new DynamicRepositoryInvokerFactory(repositories(), repositoryInvokerFactory); } @@ -109,14 +109,10 @@ public ConfigurationHandlerMethodArgumentResolver configurationHandlerMethodArgu public FileManipulationRepositoryEventListener domainRepositoryEventListener(GlobalAdministrationConfiguration configuration, FileResourceStorage fileResourceStorage) { return new FileManipulationRepositoryEventListener(configuration, fileResourceStorage); } - - @Override - protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { - config.setDefaultPageSize(10); - config.setBasePath(lightAdminConfiguration().getApplicationRestBasePath()); - config.exposeIdsFor(globalAdministrationConfiguration().getAllDomainTypesAsArray()); - config.setReturnBodyOnCreate(true); - config.setReturnBodyOnUpdate(true); + + @Bean + public RepositoryRestConfigurer lightAdminRepositoryRestConfigurer() { + return new LightAdminRepositoryRestConfigurer(); } @Override @@ -126,23 +122,12 @@ public RequestMappingHandlerAdapter repositoryExporterHandlerAdapter() { return requestMappingHandlerAdapter; } - @Override - protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { - validatingListener.addValidator("beforeCreate", validator()); - validatingListener.addValidator("beforeSave", validator()); - } - @Override public void addArgumentResolvers(List argumentResolvers) { super.addArgumentResolvers(argumentResolvers); argumentResolvers.add(configurationHandlerMethodArgumentResolver()); } - @Override - protected void configureJacksonObjectMapper(ObjectMapper objectMapper) { - objectMapper.registerModule(new LightAdminJacksonModule(globalAdministrationConfiguration())); - } - @SuppressWarnings("unchecked") private void configureRepositoryExporterHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) { List defaultArgumentResolvers = (List) forDirectFieldAccess(requestMappingHandlerAdapter).getPropertyValue("argumentResolvers"); @@ -175,10 +160,6 @@ private FileResourceStorage fileResourceStorage() { return beanFactory.getBean(FileResourceStorage.class); } - private Validator validator() { - return beanFactory.getBean("validator", Validator.class); - } - private LightAdminConfiguration lightAdminConfiguration() { return beanFactory.getBean(LightAdminConfiguration.class); } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java index abce5332..8db2159c 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java @@ -17,9 +17,6 @@ import static java.lang.String.format; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - public enum DomainConfigurationUnitType { SCREEN_CONTEXT("screenContext"), @@ -34,12 +31,10 @@ public enum DomainConfigurationUnitType { private final String name; - @JsonCreator private DomainConfigurationUnitType(final String name) { this.name = name; } - @JsonValue public String getName() { return name; } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java index f8a09d9f..e9fed022 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java @@ -17,17 +17,13 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.PersistentEntities; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.data.repository.support.Repositories; -import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.core.support.SelfLinkProvider; import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler; +import org.springframework.data.rest.webmvc.mapping.Associations; import org.springframework.data.rest.webmvc.support.Projector; -import org.springframework.hateoas.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.util.Assert; -import java.io.Serializable; - import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; /** @@ -36,9 +32,9 @@ * @author Maxim Kharchenko (kharchenko.max@gmail.com) */ public class DynamicPersistentEntityResourceAssembler extends PersistentEntityResourceAssembler { - + public DynamicPersistentEntityResourceAssembler(PersistentEntityResourceAssembler resourceAssembler) { - super(entities(resourceAssembler), entityLinks(resourceAssembler), projector(resourceAssembler), mappings(resourceAssembler)); + super(entities(resourceAssembler), projector(resourceAssembler), associations(resourceAssembler), linkProvider(resourceAssembler)); } /** @@ -48,42 +44,38 @@ public DynamicPersistentEntityResourceAssembler(PersistentEntityResourceAssemble public Link getSelfLinkFor(Object instance) { Assert.notNull(instance, "Domain object must not be null!"); - Repositories repositories = repositories(this); - - Class instanceType = instance.getClass(); - PersistentEntity entity = repositories.getPersistentEntity(instanceType); + @SuppressWarnings("rawtypes") + Class instanceType = instance.getClass(); + PersistentEntity entity = entities(this).getPersistentEntity(instanceType); if (entity == null) { throw new IllegalArgumentException(String.format("Cannot create self link for %s! No persistent entity found!", instanceType)); } - EntityInformation entityInformation = repositories.getEntityInformationFor(instanceType); - Serializable id = entityInformation.getId(instance); + Object id = entity.getIdentifierAccessor(instance).getIdentifier(); if (id == null) { - return entityLinks(this).linkToCollectionResource(entity.getType()).withSelfRel(); + throw new IllegalArgumentException(String.format("Cannot create self link for %s of Type: %s! No Id found!", + instance, instanceType)); } - return entityLinks(this).linkToSingleResource(entity.getType(), id).withSelfRel(); - } - - private static Repositories repositories(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (Repositories) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("repositories"); - } - private static EntityLinks entityLinks(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (EntityLinks) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("entityLinks"); + return super.getSelfLinkFor(instance); } private static Projector projector(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { return (Projector) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("projector"); } - private static ResourceMappings mappings(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (ResourceMappings) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("mappings"); - } - private static PersistentEntities entities(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { return (PersistentEntities) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("entities"); } + + private static Associations associations(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (Associations) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("associations"); + } + + private static SelfLinkProvider linkProvider(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { + return (SelfLinkProvider) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("linkProvider"); + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java index 2ee1616f..80bd57d4 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java @@ -1,305 +1,308 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.web.support; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.lightadmin.api.config.utils.EntityNameExtractor; -import org.lightadmin.core.config.domain.DomainTypeAdministrationConfiguration; -import org.lightadmin.core.config.domain.DomainTypeBasicConfiguration; -import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; -import org.lightadmin.core.config.domain.field.FieldMetadata; -import org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType; -import org.lightadmin.core.persistence.metamodel.PersistentPropertyType; -import org.lightadmin.core.storage.FileResourceStorage; -import org.springframework.data.mapping.*; -import org.springframework.data.rest.core.mapping.ResourceMappings; -import org.springframework.data.rest.webmvc.PersistentEntityResource; -import org.springframework.data.rest.webmvc.mapping.AssociationLinks; -import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; -import org.springframework.hateoas.Link; -import org.springframework.hateoas.ResourceProcessor; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Maps.newHashMap; -import static com.google.common.collect.Maps.newLinkedHashMap; -import static org.lightadmin.core.config.domain.configuration.support.ExceptionAwareTransformer.exceptionAwareNameExtractor; -import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.customFields; -import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.transientFields; -import static org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType.*; -import static org.lightadmin.core.persistence.metamodel.PersistentPropertyType.FILE; -import static org.lightadmin.core.web.support.DynamicPersistentEntityResourceProcessor.PersistentEntityWrapper.persistentEntity; - -@SuppressWarnings(value = {"unchecked", "unused"}) -public class DynamicPersistentEntityResourceProcessor implements ResourceProcessor { - - private final GlobalAdministrationConfiguration adminConfiguration; - private final DynamicRepositoryEntityLinks entityLinks; - private final DomainEntityLinks domainEntityLinks; - private final FileResourceStorage fileResourceStorage; - private final AssociationLinks associationLinks; - - public DynamicPersistentEntityResourceProcessor(GlobalAdministrationConfiguration adminConfiguration, FileResourceStorage fileResourceStorage, DynamicRepositoryEntityLinks entityLinks, DomainEntityLinks domainEntityLinks, ResourceMappings resourceMappings) { - this.adminConfiguration = adminConfiguration; - this.domainEntityLinks = domainEntityLinks; - this.entityLinks = entityLinks; - this.fileResourceStorage = fileResourceStorage; - this.associationLinks = new AssociationLinks(resourceMappings); - } - - @Override - public PersistentEntityResource process(PersistentEntityResource persistentEntityResource) { - PersistentEntity persistentEntity = persistentEntityResource.getPersistentEntity(); - Object value = persistentEntityResource.getContent(); - Link[] links = persistentEntityResource.getLinks().toArray(new Link[persistentEntityResource.getLinks().size()]); - - String stringRepresentation = stringRepresentation(value, persistentEntity); - Link domainLink = domainLink(persistentEntityResource); - boolean managedDomainType = adminConfiguration.isManagedDomainType(persistentEntity.getType()); - String primaryKey = primaryKey(persistentEntity); - - Map> dynamicProperties = dynamicPropertiesPerUnit(value, persistentEntity); - - PersistentEntityWrapper persistentEntityWrapper = persistentEntity(value, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); - - PersistentEntityResource.Builder builder = PersistentEntityResource.build(persistentEntityWrapper, persistentEntity); - for (Link link: links) { - builder = builder.withLink(link); - } - return builder.build(); - } - - private String primaryKey(PersistentEntity persistentEntity) { - return persistentEntity.getIdProperty().getName(); - } - - private String stringRepresentation(Object value, PersistentEntity persistentEntity) { - DomainTypeBasicConfiguration domainTypeBasicConfiguration = adminConfiguration.forDomainType(persistentEntity.getType()); - EntityNameExtractor nameExtractor = domainTypeBasicConfiguration.getEntityConfiguration().getNameExtractor(); - - return exceptionAwareNameExtractor(nameExtractor, domainTypeBasicConfiguration).apply(value); - } - - private Link domainLink(PersistentEntityResource persistentEntityResource) { - PersistentEntity persistentEntity = persistentEntityResource.getPersistentEntity(); - if (domainEntityLinks.supports(persistentEntity.getType())) { - return domainEntityLinks.linkFor(persistentEntityResource); - } - return null; - } - - private Map> dynamicPropertiesPerUnit(Object value, PersistentEntity persistentEntity) { - if (!adminConfiguration.isManagedDomainType(persistentEntity.getType())) { - return Collections.emptyMap(); - } - - DomainTypeAdministrationConfiguration managedDomainTypeConfiguration = adminConfiguration.forManagedDomainType(persistentEntity.getType()); - - List units = newArrayList(LIST_VIEW, FORM_VIEW, SHOW_VIEW, QUICK_VIEW); - - List persistentProperties = findPersistentFileProperties(persistentEntity); - List associations = findLinkableAssociations(persistentEntity); - - Map> dynamicPropertiesPerUnit = newHashMap(); - for (DomainConfigurationUnitType unit : units) { - Map dynamicProperties = newLinkedHashMap(); - for (PersistentProperty persistentProperty : persistentProperties) { - dynamicProperties.put(persistentProperty.getName(), filePropertyValue(persistentProperty, value)); - } - for (Association association : associations) { - dynamicProperties.put(association.getInverse().getName(), associationPropertyValue(association, value)); - } - for (FieldMetadata customField : customFields(managedDomainTypeConfiguration.fieldsForUnit(unit))) { - dynamicProperties.put(customField.getUuid(), customField.getValue(value)); - } - for (FieldMetadata transientField : transientFields(managedDomainTypeConfiguration.fieldsForUnit(unit))) { - dynamicProperties.put(transientField.getUuid(), transientField.getValue(value)); - } - dynamicPropertiesPerUnit.put(unit, dynamicProperties); - } - return dynamicPropertiesPerUnit; - } - - private Object associationPropertyValue(Association association, Object instance) { - PersistentProperty persistentProperty = association.getInverse(); - PersistentEntity persistentEntity = persistentProperty.getOwner(); - - if (persistentProperty.isMap()) { - return null; - } - - if (persistentProperty.isCollectionLike()) { - return associatedPersistentEntities(association, instance); - } - - Object associationValue = beanWrapper(instance).getPropertyValue(persistentProperty.getName()); - - return associatedPersistentEntity(persistentProperty, associationValue); - } - - private List associatedPersistentEntities(Association association, Object instance) { - PersistentProperty persistentProperty = association.getInverse(); - - Object associationValue = beanWrapper(instance).getPropertyValue(persistentProperty.getName()); - if (associationValue == null) { - return null; - } - - List result = newArrayList(); - - if (persistentProperty.isArray()) { - for (Object item : (Object[]) associationValue) { - result.add(associatedPersistentEntity(persistentProperty, item)); - } - return result; - } - - for (Object item : (Iterable) associationValue) { - result.add(associatedPersistentEntity(persistentProperty, item)); - } - return result; - } - - private PersistentEntityWrapper associatedPersistentEntity(PersistentProperty persistentProperty, Object associationValue) { - if (associationValue == null) { - return null; - } - - Class associationType = persistentProperty.getActualType(); - boolean managedDomainType = adminConfiguration.isManagedDomainType(associationType); - PersistentEntity associationPersistentEntity = adminConfiguration.forDomainType(associationType).getPersistentEntity(); - - String stringRepresentation = stringRepresentation(associationValue, associationPersistentEntity); - String primaryKey = primaryKey(associationPersistentEntity); - Object primaryKeyValue = beanWrapper(associationValue).getPropertyValue(primaryKey); - - Link domainLink = null; - if (domainEntityLinks.supports(associationType)) { - domainLink = domainEntityLinks.linkToSingleResource(associationType, primaryKeyValue); - } - - return PersistentEntityWrapper.associatedPersistentEntity(stringRepresentation, managedDomainType, primaryKey, primaryKeyValue, domainLink); - } - - private static DirectFieldAccessFallbackBeanWrapper beanWrapper(Object instance) { - return new DirectFieldAccessFallbackBeanWrapper(instance); - } - - private List findPersistentFileProperties(PersistentEntity persistentEntity) { - final List result = newArrayList(); - persistentEntity.doWithProperties(new SimplePropertyHandler() { - @Override - public void doWithPersistentProperty(PersistentProperty property) { - if (PersistentPropertyType.forPersistentProperty(property) == FILE) { - result.add(property); - } - } - }); - return result; - } - - private List findLinkableAssociations(PersistentEntity persistentEntity) { - final List result = newArrayList(); - persistentEntity.doWithAssociations(new SimpleAssociationHandler() { - @Override - public void doWithAssociation(Association> association) { - if (associationLinks.isLinkableAssociation(association.getInverse())) { - result.add(association); - } - } - }); - return result; - } - - private FilePropertyValue filePropertyValue(PersistentProperty persistentProperty, Object value) { - try { - if (!fileResourceStorage.fileExists(value, persistentProperty)) { - return new FilePropertyValue(false); - } - return new FilePropertyValue(entityLinks.linkForFilePropertyLink(value, persistentProperty)); - } catch (Exception e) { - return null; - } - } - - static class PersistentEntityWrapper { - private String stringRepresentation; - private boolean managedDomainType; - private String primaryKey; - private Link domainLink; - private Object persistentEntity; - private Map> dynamicProperties; - - private PersistentEntityWrapper(Object persistentEntity, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { - this.stringRepresentation = stringRepresentation; - this.domainLink = domainLink; - this.managedDomainType = managedDomainType; - this.persistentEntity = persistentEntity; - this.dynamicProperties = dynamicProperties; - this.primaryKey = primaryKey; - } - - public static PersistentEntityWrapper associatedPersistentEntity(String stringRepresentation, boolean managedDomainType, String primaryKey, Object primaryKeyValue, Link domainLink) { - Map persistentEntity = newHashMap(); - persistentEntity.put(primaryKey, primaryKeyValue); - - return new PersistentEntityWrapper(persistentEntity, null, stringRepresentation, domainLink, managedDomainType, primaryKey); - } - - public static PersistentEntityWrapper persistentEntity(Object instance, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { - return new PersistentEntityWrapper(instance, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); - } - - @JsonProperty("string_representation") - public String getStringRepresentation() { - return stringRepresentation; - } - - @JsonProperty("primary_key") - public String getPrimaryKey() { - return primaryKey; - } - - @JsonProperty("managed_type") - public boolean isManagedDomainType() { - return managedDomainType; - } - - @JsonProperty("domain_link") - @JsonInclude(NON_NULL) - public Link getDomainLink() { - return domainLink; - } - - @JsonProperty("original_properties") - @JsonInclude(NON_NULL) - public Object getPersistentEntity() { - return persistentEntity; - } - - @JsonProperty("dynamic_properties") - @JsonInclude(NON_EMPTY) - public Map> getDynamicProperties() { - return dynamicProperties; - } - } +/* + * Copyright 2012-2014 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.lightadmin.core.web.support; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.lightadmin.api.config.utils.EntityNameExtractor; +import org.lightadmin.core.config.domain.DomainTypeAdministrationConfiguration; +import org.lightadmin.core.config.domain.DomainTypeBasicConfiguration; +import org.lightadmin.core.config.domain.GlobalAdministrationConfiguration; +import org.lightadmin.core.config.domain.field.FieldMetadata; +import org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType; +import org.lightadmin.core.persistence.metamodel.PersistentPropertyType; +import org.lightadmin.core.storage.FileResourceStorage; +import org.springframework.data.mapping.*; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.webmvc.PersistentEntityResource; +import org.springframework.data.rest.webmvc.mapping.Associations; +import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.ResourceProcessor; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.collect.Maps.newLinkedHashMap; +import static org.lightadmin.core.config.domain.configuration.support.ExceptionAwareTransformer.exceptionAwareNameExtractor; +import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.customFields; +import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.transientFields; +import static org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType.*; +import static org.lightadmin.core.persistence.metamodel.PersistentPropertyType.FILE; +import static org.lightadmin.core.web.support.DynamicPersistentEntityResourceProcessor.PersistentEntityWrapper.persistentEntity; + +@SuppressWarnings(value = {"unchecked", "unused"}) +public class DynamicPersistentEntityResourceProcessor implements ResourceProcessor { + + private final GlobalAdministrationConfiguration adminConfiguration; + private final DynamicRepositoryEntityLinks entityLinks; + private final DomainEntityLinks domainEntityLinks; + private final FileResourceStorage fileResourceStorage; + private Associations associations; + + public DynamicPersistentEntityResourceProcessor(GlobalAdministrationConfiguration adminConfiguration, + FileResourceStorage fileResourceStorage, DynamicRepositoryEntityLinks entityLinks, + DomainEntityLinks domainEntityLinks, ResourceMappings resourceMappings, Associations associations) { + this.adminConfiguration = adminConfiguration; + this.domainEntityLinks = domainEntityLinks; + this.entityLinks = entityLinks; + this.fileResourceStorage = fileResourceStorage; + this.associations = associations; + } + + @Override + public PersistentEntityResource process(PersistentEntityResource persistentEntityResource) { + PersistentEntity persistentEntity = persistentEntityResource.getPersistentEntity(); + Object value = persistentEntityResource.getContent(); + Link[] links = persistentEntityResource.getLinks().toArray(new Link[persistentEntityResource.getLinks().size()]); + + String stringRepresentation = stringRepresentation(value, persistentEntity); + Link domainLink = domainLink(persistentEntityResource); + boolean managedDomainType = adminConfiguration.isManagedDomainType(persistentEntity.getType()); + String primaryKey = primaryKey(persistentEntity); + + Map> dynamicProperties = dynamicPropertiesPerUnit(value, persistentEntity); + + PersistentEntityWrapper persistentEntityWrapper = persistentEntity(value, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); + + PersistentEntityResource.Builder builder = PersistentEntityResource.build(persistentEntityWrapper, persistentEntity); + for (Link link: links) { + builder = builder.withLink(link); + } + return builder.build(); + } + + private String primaryKey(PersistentEntity persistentEntity) { + return persistentEntity.getIdProperty().getName(); + } + + private String stringRepresentation(Object value, PersistentEntity persistentEntity) { + DomainTypeBasicConfiguration domainTypeBasicConfiguration = adminConfiguration.forDomainType(persistentEntity.getType()); + EntityNameExtractor nameExtractor = domainTypeBasicConfiguration.getEntityConfiguration().getNameExtractor(); + + return exceptionAwareNameExtractor(nameExtractor, domainTypeBasicConfiguration).apply(value); + } + + private Link domainLink(PersistentEntityResource persistentEntityResource) { + PersistentEntity persistentEntity = persistentEntityResource.getPersistentEntity(); + if (domainEntityLinks.supports(persistentEntity.getType())) { + return domainEntityLinks.linkFor(persistentEntityResource); + } + return null; + } + + private Map> dynamicPropertiesPerUnit(Object value, PersistentEntity persistentEntity) { + if (!adminConfiguration.isManagedDomainType(persistentEntity.getType())) { + return Collections.emptyMap(); + } + + DomainTypeAdministrationConfiguration managedDomainTypeConfiguration = adminConfiguration.forManagedDomainType(persistentEntity.getType()); + + List units = newArrayList(LIST_VIEW, FORM_VIEW, SHOW_VIEW, QUICK_VIEW); + + List persistentProperties = findPersistentFileProperties(persistentEntity); + List associations = findLinkableAssociations(persistentEntity); + + Map> dynamicPropertiesPerUnit = newHashMap(); + for (DomainConfigurationUnitType unit : units) { + Map dynamicProperties = newLinkedHashMap(); + for (PersistentProperty persistentProperty : persistentProperties) { + dynamicProperties.put(persistentProperty.getName(), filePropertyValue(persistentProperty, value)); + } + for (Association association : associations) { + dynamicProperties.put(association.getInverse().getName(), associationPropertyValue(association, value)); + } + for (FieldMetadata customField : customFields(managedDomainTypeConfiguration.fieldsForUnit(unit))) { + dynamicProperties.put(customField.getUuid(), customField.getValue(value)); + } + for (FieldMetadata transientField : transientFields(managedDomainTypeConfiguration.fieldsForUnit(unit))) { + dynamicProperties.put(transientField.getUuid(), transientField.getValue(value)); + } + dynamicPropertiesPerUnit.put(unit, dynamicProperties); + } + return dynamicPropertiesPerUnit; + } + + private Object associationPropertyValue(Association association, Object instance) { + PersistentProperty persistentProperty = association.getInverse(); + PersistentEntity persistentEntity = persistentProperty.getOwner(); + + if (persistentProperty.isMap()) { + return null; + } + + if (persistentProperty.isCollectionLike()) { + return associatedPersistentEntities(association, instance); + } + + Object associationValue = beanWrapper(instance).getPropertyValue(persistentProperty.getName()); + + return associatedPersistentEntity(persistentProperty, associationValue); + } + + private List associatedPersistentEntities(Association association, Object instance) { + PersistentProperty persistentProperty = association.getInverse(); + + Object associationValue = beanWrapper(instance).getPropertyValue(persistentProperty.getName()); + if (associationValue == null) { + return null; + } + + List result = newArrayList(); + + if (persistentProperty.isArray()) { + for (Object item : (Object[]) associationValue) { + result.add(associatedPersistentEntity(persistentProperty, item)); + } + return result; + } + + for (Object item : (Iterable) associationValue) { + result.add(associatedPersistentEntity(persistentProperty, item)); + } + return result; + } + + private PersistentEntityWrapper associatedPersistentEntity(PersistentProperty persistentProperty, Object associationValue) { + if (associationValue == null) { + return null; + } + + Class associationType = persistentProperty.getActualType(); + boolean managedDomainType = adminConfiguration.isManagedDomainType(associationType); + PersistentEntity associationPersistentEntity = adminConfiguration.forDomainType(associationType).getPersistentEntity(); + + String stringRepresentation = stringRepresentation(associationValue, associationPersistentEntity); + String primaryKey = primaryKey(associationPersistentEntity); + Object primaryKeyValue = beanWrapper(associationValue).getPropertyValue(primaryKey); + + Link domainLink = null; + if (domainEntityLinks.supports(associationType)) { + domainLink = domainEntityLinks.linkToSingleResource(associationType, primaryKeyValue); + } + + return PersistentEntityWrapper.associatedPersistentEntity(stringRepresentation, managedDomainType, primaryKey, primaryKeyValue, domainLink); + } + + private static DirectFieldAccessFallbackBeanWrapper beanWrapper(Object instance) { + return new DirectFieldAccessFallbackBeanWrapper(instance); + } + + private List findPersistentFileProperties(PersistentEntity persistentEntity) { + final List result = newArrayList(); + persistentEntity.doWithProperties(new SimplePropertyHandler() { + @Override + public void doWithPersistentProperty(PersistentProperty property) { + if (PersistentPropertyType.forPersistentProperty(property) == FILE) { + result.add(property); + } + } + }); + return result; + } + + private List findLinkableAssociations(PersistentEntity persistentEntity) { + final List result = newArrayList(); + persistentEntity.doWithAssociations(new SimpleAssociationHandler() { + @Override + public void doWithAssociation(Association> association) { + if (associations.isLinkableAssociation(association.getInverse())) { + result.add(association); + } + } + }); + return result; + } + + private FilePropertyValue filePropertyValue(PersistentProperty persistentProperty, Object value) { + try { + if (!fileResourceStorage.fileExists(value, persistentProperty)) { + return new FilePropertyValue(false); + } + return new FilePropertyValue(entityLinks.linkForFilePropertyLink(value, persistentProperty)); + } catch (Exception e) { + return null; + } + } + + static class PersistentEntityWrapper { + private String stringRepresentation; + private boolean managedDomainType; + private String primaryKey; + private Link domainLink; + private Object persistentEntity; + private Map> dynamicProperties; + + private PersistentEntityWrapper(Object persistentEntity, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { + this.stringRepresentation = stringRepresentation; + this.domainLink = domainLink; + this.managedDomainType = managedDomainType; + this.persistentEntity = persistentEntity; + this.dynamicProperties = dynamicProperties; + this.primaryKey = primaryKey; + } + + public static PersistentEntityWrapper associatedPersistentEntity(String stringRepresentation, boolean managedDomainType, String primaryKey, Object primaryKeyValue, Link domainLink) { + Map persistentEntity = newHashMap(); + persistentEntity.put(primaryKey, primaryKeyValue); + + return new PersistentEntityWrapper(persistentEntity, null, stringRepresentation, domainLink, managedDomainType, primaryKey); + } + + public static PersistentEntityWrapper persistentEntity(Object instance, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { + return new PersistentEntityWrapper(instance, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); + } + + @JsonProperty("string_representation") + public String getStringRepresentation() { + return stringRepresentation; + } + + @JsonProperty("primary_key") + public String getPrimaryKey() { + return primaryKey; + } + + @JsonProperty("managed_type") + public boolean isManagedDomainType() { + return managedDomainType; + } + + @JsonProperty("domain_link") + @JsonInclude(NON_NULL) + public Link getDomainLink() { + return domainLink; + } + + @JsonProperty("original_properties") + @JsonInclude(NON_NULL) + public Object getPersistentEntity() { + return persistentEntity; + } + + @JsonProperty("dynamic_properties") + @JsonInclude(NON_EMPTY) + public Map> getDynamicProperties() { + return dynamicProperties; + } + } } \ No newline at end of file From 2be1bc5297cb2f28d8559fe1e75c566074bd85b5 Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 8 Mar 2018 12:25:47 -0500 Subject: [PATCH 13/18] Issue that the Jackson Object mapper could not parse PersistentEntityWrapper instances, is fixed. --- ...htAdminRepositoryRestMvcConfiguration.java | 6 + ...amicPersistentEntityResourceProcessor.java | 65 +------ .../web/support/LightAdminLinkCollector.java | 159 ++++++++++++++++++ .../web/support/PersistentEntityWrapper.java | 88 ++++++++++ 4 files changed, 254 insertions(+), 64 deletions(-) create mode 100644 lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java create mode 100644 lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java 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 3839b5de..c34aed58 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 @@ -39,6 +39,7 @@ import org.springframework.data.rest.webmvc.config.PersistentEntityResourceAssemblerArgumentResolver; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; +import org.springframework.data.rest.webmvc.mapping.LinkCollector; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; @@ -127,6 +128,11 @@ public void addArgumentResolvers(List argumentRes super.addArgumentResolvers(argumentResolvers); argumentResolvers.add(configurationHandlerMethodArgumentResolver()); } + + @Override + protected LinkCollector linkCollector() { + return new LightAdminLinkCollector(persistentEntities(), selfLinkProvider(), associationLinks()); + } @SuppressWarnings("unchecked") private void configureRepositoryExporterHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) { diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java index 80bd57d4..dee14a98 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceProcessor.java @@ -48,7 +48,6 @@ import static org.lightadmin.core.config.domain.field.FieldMetadataUtils.transientFields; import static org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType.*; import static org.lightadmin.core.persistence.metamodel.PersistentPropertyType.FILE; -import static org.lightadmin.core.web.support.DynamicPersistentEntityResourceProcessor.PersistentEntityWrapper.persistentEntity; @SuppressWarnings(value = {"unchecked", "unused"}) public class DynamicPersistentEntityResourceProcessor implements ResourceProcessor { @@ -82,7 +81,7 @@ public PersistentEntityResource process(PersistentEntityResource persistentEntit Map> dynamicProperties = dynamicPropertiesPerUnit(value, persistentEntity); - PersistentEntityWrapper persistentEntityWrapper = persistentEntity(value, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); + PersistentEntityWrapper persistentEntityWrapper = PersistentEntityWrapper.persistentEntity(value, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); PersistentEntityResource.Builder builder = PersistentEntityResource.build(persistentEntityWrapper, persistentEntity); for (Link link: links) { @@ -243,66 +242,4 @@ private FilePropertyValue filePropertyValue(PersistentProperty persistentPropert return null; } } - - static class PersistentEntityWrapper { - private String stringRepresentation; - private boolean managedDomainType; - private String primaryKey; - private Link domainLink; - private Object persistentEntity; - private Map> dynamicProperties; - - private PersistentEntityWrapper(Object persistentEntity, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { - this.stringRepresentation = stringRepresentation; - this.domainLink = domainLink; - this.managedDomainType = managedDomainType; - this.persistentEntity = persistentEntity; - this.dynamicProperties = dynamicProperties; - this.primaryKey = primaryKey; - } - - public static PersistentEntityWrapper associatedPersistentEntity(String stringRepresentation, boolean managedDomainType, String primaryKey, Object primaryKeyValue, Link domainLink) { - Map persistentEntity = newHashMap(); - persistentEntity.put(primaryKey, primaryKeyValue); - - return new PersistentEntityWrapper(persistentEntity, null, stringRepresentation, domainLink, managedDomainType, primaryKey); - } - - public static PersistentEntityWrapper persistentEntity(Object instance, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { - return new PersistentEntityWrapper(instance, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); - } - - @JsonProperty("string_representation") - public String getStringRepresentation() { - return stringRepresentation; - } - - @JsonProperty("primary_key") - public String getPrimaryKey() { - return primaryKey; - } - - @JsonProperty("managed_type") - public boolean isManagedDomainType() { - return managedDomainType; - } - - @JsonProperty("domain_link") - @JsonInclude(NON_NULL) - public Link getDomainLink() { - return domainLink; - } - - @JsonProperty("original_properties") - @JsonInclude(NON_NULL) - public Object getPersistentEntity() { - return persistentEntity; - } - - @JsonProperty("dynamic_properties") - @JsonInclude(NON_EMPTY) - public Map> getDynamicProperties() { - return dynamicProperties; - } - } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java new file mode 100644 index 00000000..2341e4e5 --- /dev/null +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java @@ -0,0 +1,159 @@ +/** + * + */ +package org.lightadmin.core.web.support; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.mapping.Association; +import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.PersistentProperty; +import org.springframework.data.mapping.SimpleAssociationHandler; +import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.rest.core.Path; +import org.springframework.data.rest.core.support.SelfLinkProvider; +import org.springframework.data.rest.webmvc.mapping.Associations; +import org.springframework.data.rest.webmvc.mapping.LinkCollector; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.Links; +import org.springframework.util.Assert; + +/** + * Overriding default {@link LinkCollector} so that correct + * Persistent Entity (not the {@link PersistentEntityWrapper} is + * used to generate the links. + * + * @author Gazi Rahman + * + */ +public class LightAdminLinkCollector extends org.springframework.data.rest.webmvc.mapping.LinkCollector { + + private PersistentEntities entities; + + private SelfLinkProvider links; + + private Associations associationLinks; + + /** + * @param entities + * @param linkProvider + * @param associationLinks + */ + public LightAdminLinkCollector(PersistentEntities entities, SelfLinkProvider linkProvider, Associations associationLinks) { + super(entities, linkProvider, associationLinks); + this.entities = entities; + this.links = linkProvider; + this.associationLinks = associationLinks; + } + + @Override + public Links getLinksFor(Object object, List existingLinks) { + + Assert.notNull(object, "Object must not be null!"); + Assert.notNull(existingLinks, "Existing links must not be null!"); + + if (object instanceof PersistentEntityWrapper) { + object = ((PersistentEntityWrapper) object).getPersistentEntity(); + } + + PersistentEntity entity = entities.getPersistentEntity(object.getClass()); + + Links links = new Links(existingLinks); + Link selfLink = createSelfLink(object, links); + + if (selfLink == null) { + return links; + } + + Path path = new Path(selfLink.expand().getHref()); + + LinkCollectingAssociationHandler handler = new LinkCollectingAssociationHandler(entities, path, associationLinks); + entity.doWithAssociations(handler); + + List result = new ArrayList(existingLinks); + result.addAll(handler.getLinks()); + + return addSelfLinkIfNecessary(object, result); + } + + private Links addSelfLinkIfNecessary(Object object, List existing) { + + Links result = new Links(existing); + + if (result.hasLink(Link.REL_SELF)) { + return result; + } + + List list = new ArrayList(); + list.add(createSelfLink(object, result)); + list.addAll(existing); + + return new Links(list); + } + + private Link createSelfLink(Object object, Links existing) { + + if (existing.hasLink(Link.REL_SELF)) { + return existing.getLink(Link.REL_SELF); + } + + return links.createSelfLinkFor(object).withSelfRel(); + } + + /** + * {@link SimpleAssociationHandler} that will collect {@link Link}s for all linkable associations. + * + * @author Oliver Gierke + * @since 2.1 + */ + private static class LinkCollectingAssociationHandler implements SimpleAssociationHandler { + + private static final String AMBIGUOUS_ASSOCIATIONS = "Detected multiple association links with same relation type! Disambiguate association %s using @RestResource!"; + + @SuppressWarnings("unused") + private final PersistentEntities entities; + private final Path basePath; + private final Associations associationLinks; + private final List links = new ArrayList(); + + public LinkCollectingAssociationHandler(PersistentEntities entities, Path basePath, Associations associationLink) { + this.entities = entities; + this.basePath = basePath; + this.associationLinks = associationLink; + } + + /** + * Returns the links collected after the {@link Association} has been traversed. + * + * @return the links + */ + public List getLinks() { + return links; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.mapping.SimpleAssociationHandler#doWithAssociation(org.springframework.data.mapping.Association) + */ + @Override + public void doWithAssociation(final Association> association) { + + if (associationLinks.isLinkableAssociation(association)) { + + PersistentProperty property = association.getInverse(); + Links existingLinks = new Links(links); + + for (Link link : associationLinks.getLinksFor(association, basePath)) { + if (existingLinks.hasLink(link.getRel())) { + throw new MappingException(String.format(AMBIGUOUS_ASSOCIATIONS, property.toString())); + } else { + links.add(link); + } + } + } + } + } + +} diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java new file mode 100644 index 00000000..f24f9944 --- /dev/null +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java @@ -0,0 +1,88 @@ +/** + * + */ +package org.lightadmin.core.web.support; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; +import static com.google.common.collect.Maps.newHashMap; + +import java.util.Map; + +import org.lightadmin.core.config.domain.unit.DomainConfigurationUnitType; +import org.springframework.hateoas.Link; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Wraps all the Persistent Entities. + *

+ * This class is moved out of {@link DynamicPersistentEntityResourceProcessor} + * so that it can be used in other classes as well, like the {@link LightAdminLinkCollector}. + * + * @author Gazi Rahman + * + */ + +public class PersistentEntityWrapper { + private String stringRepresentation; + private boolean managedDomainType; + private String primaryKey; + private Link domainLink; + private Object persistentEntity; + private Map> dynamicProperties; + + private PersistentEntityWrapper(Object persistentEntity, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { + this.stringRepresentation = stringRepresentation; + this.domainLink = domainLink; + this.managedDomainType = managedDomainType; + this.persistentEntity = persistentEntity; + this.dynamicProperties = dynamicProperties; + this.primaryKey = primaryKey; + } + + public static PersistentEntityWrapper associatedPersistentEntity(String stringRepresentation, boolean managedDomainType, String primaryKey, Object primaryKeyValue, Link domainLink) { + Map persistentEntity = newHashMap(); + persistentEntity.put(primaryKey, primaryKeyValue); + + return new PersistentEntityWrapper(persistentEntity, null, stringRepresentation, domainLink, managedDomainType, primaryKey); + } + + public static PersistentEntityWrapper persistentEntity(Object instance, Map> dynamicProperties, String stringRepresentation, Link domainLink, boolean managedDomainType, String primaryKey) { + return new PersistentEntityWrapper(instance, dynamicProperties, stringRepresentation, domainLink, managedDomainType, primaryKey); + } + + @JsonProperty("string_representation") + public String getStringRepresentation() { + return stringRepresentation; + } + + @JsonProperty("primary_key") + public String getPrimaryKey() { + return primaryKey; + } + + @JsonProperty("managed_type") + public boolean isManagedDomainType() { + return managedDomainType; + } + + @JsonProperty("domain_link") + @JsonInclude(NON_NULL) + public Link getDomainLink() { + return domainLink; + } + + @JsonProperty("original_properties") + @JsonInclude(NON_NULL) + public Object getPersistentEntity() { + return persistentEntity; + } + + @JsonProperty("dynamic_properties") + @JsonInclude(NON_EMPTY) + public Map> getDynamicProperties() { + return dynamicProperties; + } +} From e39d4fdebda78a8007c83cb0cdf08f11a76c6083 Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 8 Mar 2018 12:26:27 -0500 Subject: [PATCH 14/18] Issue that view names were not properly serialized, is fixed. --- .../core/config/domain/unit/DomainConfigurationUnitType.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java index 8db2159c..b6d46b2d 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/domain/unit/DomainConfigurationUnitType.java @@ -17,6 +17,9 @@ import static java.lang.String.format; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + public enum DomainConfigurationUnitType { SCREEN_CONTEXT("screenContext"), @@ -35,10 +38,12 @@ private DomainConfigurationUnitType(final String name) { this.name = name; } + @JsonValue public String getName() { return name; } + @JsonCreator public static DomainConfigurationUnitType forName(String name) { for (DomainConfigurationUnitType domainConfigurationUnitType : values()) { if (domainConfigurationUnitType.getName().equals(name)) { From 2a9002a7b0ca3247fec8138c36956f9512c38cd6 Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 8 Mar 2018 13:34:19 -0500 Subject: [PATCH 15/18] Java 8 is needed for newer version of Spring Dependencies. --- lightadmin-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index b0fb1570..70429d2b 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -92,7 +92,7 @@ UTF-8 1.7 - 1.7 + 1.8 Brussels-SR6 From 24c7b14a59da56194d39bd7543ff135572c8280c Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 8 Mar 2018 15:17:51 -0500 Subject: [PATCH 16/18] Spring platform upgrated in theparent, sandbox and the test modules as well. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6ff0fff3..c30c0353 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.7 1.7 - 2.0.8.RELEASE + Brussels-SR6 1.2 1.0.0.BUILD-SNAPSHOT From 2b0958ca1854f4a439c9e03759427cb3b3ea17dd Mon Sep 17 00:00:00 2001 From: grahman Date: Thu, 8 Mar 2018 15:22:51 -0500 Subject: [PATCH 17/18] Compiler upgraded to Java 8 for newer Spring versions. --- lightadmin-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightadmin-core/pom.xml b/lightadmin-core/pom.xml index 70429d2b..e26710f8 100644 --- a/lightadmin-core/pom.xml +++ b/lightadmin-core/pom.xml @@ -91,7 +91,7 @@ UTF-8 UTF-8 - 1.7 + 1.8 1.8 Brussels-SR6 From 28d5789453ee7396926a73cc2abfbb5cce7a3510 Mon Sep 17 00:00:00 2001 From: grahman Date: Fri, 9 Mar 2018 12:32:41 -0500 Subject: [PATCH 18/18] Bug that new entities couldn't be created, is fixed. --- .../LightAdminRepositoryRestConfigurer.java | 12 +- ...htAdminRepositoryRestMvcConfiguration.java | 17 +- ...amicPersistentEntityResourceAssembler.java | 81 -------- ...tityResourceAssemblerArgumentResolver.java | 48 ----- .../support/DynamicRepositoryEntityLinks.java | 188 +++++++++--------- .../web/support/LightAdminLinkCollector.java | 116 +---------- .../web/support/PersistentEntityWrapper.java | 2 +- 7 files changed, 110 insertions(+), 354 deletions(-) delete mode 100644 lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java delete mode 100644 lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssemblerArgumentResolver.java diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java index c8ce59de..f8e77c71 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/config/context/LightAdminRepositoryRestConfigurer.java @@ -15,12 +15,22 @@ import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer; import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; +import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; import org.springframework.validation.Validator; import com.fasterxml.jackson.databind.ObjectMapper; /** - * @author Gazi Rahman + * {@link RepositoryRestConfigurer} for LightAdmin. + *

+ * Spring Data Web requires the configurations to be moved out of {@link RepositoryRestMvcConfiguration} + * and are configured through RepositoryRestConfigurer beans + * configured in the context. That's why these configurations are moved out from + * {@link LightAdminRepositoryRestMvcConfiguration} and placed in a separate + * RepositoryRestConfigurer class, which is then configured as a + * bean in the LightAdminRepositoryRestMvcConfiguration. + * + * @author Gazi Rahman * */ @Configuration 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 c34aed58..7488ca83 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 @@ -62,15 +62,15 @@ public DomainEntityLinks domainEntityLinks() { return new DomainEntityLinks(globalAdministrationConfiguration(), backendIdConverterRegistry(), lightAdminConfiguration()); } - @Bean - public DynamicRepositoryEntityLinks dynamicRepositoryEntityLinks() { - return DynamicRepositoryEntityLinks.wrap(super.entityLinks()); + @Override + public DynamicRepositoryEntityLinks entityLinks() { + return new DynamicRepositoryEntityLinks(super.entityLinks()); } @Bean public DynamicPersistentEntityResourceProcessor dynamicPersistentEntityResourceProcessor() { return new DynamicPersistentEntityResourceProcessor(globalAdministrationConfiguration(), - fileResourceStorage(), dynamicRepositoryEntityLinks(), domainEntityLinks(), + fileResourceStorage(), entityLinks(), domainEntityLinks(), resourceMappings(), associationLinks()); } @@ -147,14 +147,7 @@ private void configureRepositoryExporterHandlerAdapter(RequestMappingHandlerAdap private List decorateArgumentResolvers(List argumentResolvers) { List result = newLinkedList(); - for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) { - if (isAssignableValue(PersistentEntityResourceAssemblerArgumentResolver.class, argumentResolver)) { - PersistentEntityResourceAssemblerArgumentResolver persistentEntityResourceAssemblerArgumentResolver = (PersistentEntityResourceAssemblerArgumentResolver) argumentResolver; - result.add(new DynamicPersistentEntityResourceAssemblerArgumentResolver(persistentEntityResourceAssemblerArgumentResolver)); - continue; - } - result.add(argumentResolver); - } + result.addAll(argumentResolvers); return result; } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java deleted file mode 100644 index e9fed022..00000000 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssembler.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.web.support; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.context.PersistentEntities; -import org.springframework.data.rest.core.support.SelfLinkProvider; -import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler; -import org.springframework.data.rest.webmvc.mapping.Associations; -import org.springframework.data.rest.webmvc.support.Projector; -import org.springframework.hateoas.Link; -import org.springframework.util.Assert; - -import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; - -/** - * Fix of Spring Data REST related defect - * - * @author Maxim Kharchenko (kharchenko.max@gmail.com) - */ -public class DynamicPersistentEntityResourceAssembler extends PersistentEntityResourceAssembler { - - public DynamicPersistentEntityResourceAssembler(PersistentEntityResourceAssembler resourceAssembler) { - super(entities(resourceAssembler), projector(resourceAssembler), associations(resourceAssembler), linkProvider(resourceAssembler)); - } - - /** - * @see DATAREST-269 (https://jira.spring.io/browse/DATAREST-269) - */ - @Override - public Link getSelfLinkFor(Object instance) { - Assert.notNull(instance, "Domain object must not be null!"); - - @SuppressWarnings("rawtypes") - Class instanceType = instance.getClass(); - PersistentEntity entity = entities(this).getPersistentEntity(instanceType); - - if (entity == null) { - throw new IllegalArgumentException(String.format("Cannot create self link for %s! No persistent entity found!", instanceType)); - } - - Object id = entity.getIdentifierAccessor(instance).getIdentifier(); - - if (id == null) { - throw new IllegalArgumentException(String.format("Cannot create self link for %s of Type: %s! No Id found!", - instance, instanceType)); - } - - - return super.getSelfLinkFor(instance); - } - - private static Projector projector(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (Projector) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("projector"); - } - - private static PersistentEntities entities(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (PersistentEntities) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("entities"); - } - - private static Associations associations(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (Associations) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("associations"); - } - - private static SelfLinkProvider linkProvider(PersistentEntityResourceAssembler persistentEntityResourceAssembler) { - return (SelfLinkProvider) forDirectFieldAccess(persistentEntityResourceAssembler).getPropertyValue("linkProvider"); - } -} \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssemblerArgumentResolver.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssemblerArgumentResolver.java deleted file mode 100644 index d23345b6..00000000 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicPersistentEntityResourceAssemblerArgumentResolver.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.web.support; - -import org.springframework.core.MethodParameter; -import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler; -import org.springframework.data.rest.webmvc.config.PersistentEntityResourceAssemblerArgumentResolver; -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; - -/** - * @author Maxim Kharchenko (kharchenko.max@gmail.com) - */ -public class DynamicPersistentEntityResourceAssemblerArgumentResolver implements HandlerMethodArgumentResolver { - - private PersistentEntityResourceAssemblerArgumentResolver delegate; - - public DynamicPersistentEntityResourceAssemblerArgumentResolver(PersistentEntityResourceAssemblerArgumentResolver delegate) { - this.delegate = delegate; - } - - @Override - public boolean supportsParameter(MethodParameter parameter) { - return this.delegate.supportsParameter(parameter); - } - - @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - PersistentEntityResourceAssembler persistentEntityResourceAssembler = (PersistentEntityResourceAssembler) delegate.resolveArgument(parameter, mavContainer, webRequest, binderFactory); - - return new DynamicPersistentEntityResourceAssembler(persistentEntityResourceAssembler); - } -} \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicRepositoryEntityLinks.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicRepositoryEntityLinks.java index 86dc9565..fa856bfd 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicRepositoryEntityLinks.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/DynamicRepositoryEntityLinks.java @@ -1,98 +1,92 @@ -/* - * Copyright 2012-2014 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.lightadmin.core.web.support; - -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; -import org.springframework.hateoas.EntityLinks; -import org.springframework.hateoas.Identifiable; -import org.springframework.hateoas.Link; -import org.springframework.hateoas.LinkBuilder; - -import java.io.Serializable; - -/** - * TODO: Document me! - * - * @author Maxim Kharchenko (kharchenko.max@gmail.com) - */ -public class DynamicRepositoryEntityLinks implements EntityLinks { - - private EntityLinks delegate; - - private DynamicRepositoryEntityLinks(EntityLinks delegate) { - this.delegate = delegate; - } - - public static DynamicRepositoryEntityLinks wrap(EntityLinks delegate) { - return new DynamicRepositoryEntityLinks(delegate); - } - - public Link linkForFilePropertyLink(Object instance, PersistentProperty persistentProperty) { - PersistentEntity persistentEntity = persistentProperty.getOwner(); - Serializable id = idValue(instance, persistentEntity); - - return delegate.linkForSingleResource(persistentEntity.getType(), id).slash(persistentProperty.getName()).slash("file").withSelfRel(); - } - - @Override - public boolean supports(Class delimiter) { - return delegate.supports(delimiter); - } - - @Override - public LinkBuilder linkFor(Class type) { - return delegate.linkFor(type); - } - - @Override - public LinkBuilder linkFor(Class type, Object... parameters) { - return delegate.linkFor(type, parameters); - } - - @Override - public Link linkToCollectionResource(Class type) { - return delegate.linkToCollectionResource(type); - } - - @Override - public Link linkToSingleResource(Class type, Object id) { - if (id == null) { - return linkFor(type).slash("new").withSelfRel(); - } - return delegate.linkToSingleResource(type, id); - } - - @Override - public Link linkToSingleResource(Identifiable entity) { - return delegate.linkToSingleResource(entity); - } - - @Override - public LinkBuilder linkForSingleResource(Class type, Object id) { - return delegate.linkForSingleResource(type, id); - } - - @Override - public LinkBuilder linkForSingleResource(Identifiable entity) { - return delegate.linkForSingleResource(entity); - } - - private Serializable idValue(Object instance, PersistentEntity persistentEntity) { - return (Serializable) new DirectFieldAccessFallbackBeanWrapper(instance).getPropertyValue(persistentEntity.getIdProperty().getName()); - } +/* + * Copyright 2012-2014 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.lightadmin.core.web.support; + +import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mapping.PersistentProperty; +import org.springframework.data.repository.support.Repositories; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.core.mapping.ResourceMappings; +import org.springframework.data.rest.webmvc.spi.BackendIdConverter; +import org.springframework.data.rest.webmvc.support.PagingAndSortingTemplateVariables; +import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks; +import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; +import org.springframework.hateoas.EntityLinks; +import org.springframework.hateoas.Link; +import org.springframework.plugin.core.PluginRegistry; + +import java.io.Serializable; + +import static org.springframework.beans.PropertyAccessorFactory.forDirectFieldAccess; + +/** + * {@link RepositoryEntityLinks} for LightAdmin that allows creation + * of links for entities that are new (having no ID) and also adds + * support for creating links for File Properties. + * + * @author Maxim Kharchenko (kharchenko.max@gmail.com) + * @author Gazi Rahman + */ +public class DynamicRepositoryEntityLinks extends RepositoryEntityLinks implements EntityLinks { + + + public DynamicRepositoryEntityLinks(RepositoryEntityLinks delegate) { + super(repositories(delegate), mappings(delegate), config(delegate), templateVariables(delegate), idConverters(delegate)); + } + + public Link linkForFilePropertyLink(Object instance, + @SuppressWarnings("rawtypes") PersistentProperty persistentProperty) { + @SuppressWarnings("rawtypes") + PersistentEntity persistentEntity = persistentProperty.getOwner(); + Serializable id = idValue(instance, persistentEntity); + + return super.linkForSingleResource(persistentEntity.getType(), id).slash(persistentProperty.getName()).slash("file").withSelfRel(); + } + + @Override + public Link linkToSingleResource(Class type, Object id) { + if (id == null) { + return linkFor(type).slash("new").withSelfRel(); + } + return super.linkToSingleResource(type, id); + } + + private Serializable idValue(Object instance, + @SuppressWarnings("rawtypes") PersistentEntity persistentEntity) { + return (Serializable) new DirectFieldAccessFallbackBeanWrapper(instance).getPropertyValue(persistentEntity.getIdProperty().getName()); + } + + private static Repositories repositories(RepositoryEntityLinks delegate) { + return (Repositories) forDirectFieldAccess(delegate).getPropertyValue("repositories"); + } + + @SuppressWarnings("unchecked") + private static PluginRegistry> idConverters(RepositoryEntityLinks delegate) { + return (PluginRegistry>) forDirectFieldAccess(delegate).getPropertyValue("idConverters"); + } + + private static PagingAndSortingTemplateVariables templateVariables(RepositoryEntityLinks delegate) { + return (PagingAndSortingTemplateVariables) forDirectFieldAccess(delegate).getPropertyValue("templateVariables"); + } + + private static RepositoryRestConfiguration config(RepositoryEntityLinks delegate) { + return (RepositoryRestConfiguration) forDirectFieldAccess(delegate).getPropertyValue("config"); + } + + private static ResourceMappings mappings(RepositoryEntityLinks delegate) { + return (ResourceMappings) forDirectFieldAccess(delegate).getPropertyValue("mappings"); + } } \ No newline at end of file diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java index 2341e4e5..cfcdc593 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/LightAdminLinkCollector.java @@ -3,16 +3,9 @@ */ package org.lightadmin.core.web.support; -import java.util.ArrayList; import java.util.List; -import org.springframework.data.mapping.Association; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.SimpleAssociationHandler; import org.springframework.data.mapping.context.PersistentEntities; -import org.springframework.data.mapping.model.MappingException; -import org.springframework.data.rest.core.Path; import org.springframework.data.rest.core.support.SelfLinkProvider; import org.springframework.data.rest.webmvc.mapping.Associations; import org.springframework.data.rest.webmvc.mapping.LinkCollector; @@ -25,17 +18,11 @@ * Persistent Entity (not the {@link PersistentEntityWrapper} is * used to generate the links. * - * @author Gazi Rahman + * @author Gazi Rahman * */ public class LightAdminLinkCollector extends org.springframework.data.rest.webmvc.mapping.LinkCollector { - private PersistentEntities entities; - - private SelfLinkProvider links; - - private Associations associationLinks; - /** * @param entities * @param linkProvider @@ -43,117 +30,18 @@ public class LightAdminLinkCollector extends org.springframework.data.rest.webmv */ public LightAdminLinkCollector(PersistentEntities entities, SelfLinkProvider linkProvider, Associations associationLinks) { super(entities, linkProvider, associationLinks); - this.entities = entities; - this.links = linkProvider; - this.associationLinks = associationLinks; } @Override public Links getLinksFor(Object object, List existingLinks) { Assert.notNull(object, "Object must not be null!"); - Assert.notNull(existingLinks, "Existing links must not be null!"); if (object instanceof PersistentEntityWrapper) { object = ((PersistentEntityWrapper) object).getPersistentEntity(); } - PersistentEntity entity = entities.getPersistentEntity(object.getClass()); - - Links links = new Links(existingLinks); - Link selfLink = createSelfLink(object, links); - - if (selfLink == null) { - return links; - } - - Path path = new Path(selfLink.expand().getHref()); - - LinkCollectingAssociationHandler handler = new LinkCollectingAssociationHandler(entities, path, associationLinks); - entity.doWithAssociations(handler); - - List result = new ArrayList(existingLinks); - result.addAll(handler.getLinks()); - - return addSelfLinkIfNecessary(object, result); - } - - private Links addSelfLinkIfNecessary(Object object, List existing) { - - Links result = new Links(existing); - - if (result.hasLink(Link.REL_SELF)) { - return result; - } - - List list = new ArrayList(); - list.add(createSelfLink(object, result)); - list.addAll(existing); - - return new Links(list); - } - - private Link createSelfLink(Object object, Links existing) { - - if (existing.hasLink(Link.REL_SELF)) { - return existing.getLink(Link.REL_SELF); - } - - return links.createSelfLinkFor(object).withSelfRel(); - } - - /** - * {@link SimpleAssociationHandler} that will collect {@link Link}s for all linkable associations. - * - * @author Oliver Gierke - * @since 2.1 - */ - private static class LinkCollectingAssociationHandler implements SimpleAssociationHandler { - - private static final String AMBIGUOUS_ASSOCIATIONS = "Detected multiple association links with same relation type! Disambiguate association %s using @RestResource!"; - - @SuppressWarnings("unused") - private final PersistentEntities entities; - private final Path basePath; - private final Associations associationLinks; - private final List links = new ArrayList(); - - public LinkCollectingAssociationHandler(PersistentEntities entities, Path basePath, Associations associationLink) { - this.entities = entities; - this.basePath = basePath; - this.associationLinks = associationLink; - } - - /** - * Returns the links collected after the {@link Association} has been traversed. - * - * @return the links - */ - public List getLinks() { - return links; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mapping.SimpleAssociationHandler#doWithAssociation(org.springframework.data.mapping.Association) - */ - @Override - public void doWithAssociation(final Association> association) { - - if (associationLinks.isLinkableAssociation(association)) { - - PersistentProperty property = association.getInverse(); - Links existingLinks = new Links(links); - - for (Link link : associationLinks.getLinksFor(association, basePath)) { - if (existingLinks.hasLink(link.getRel())) { - throw new MappingException(String.format(AMBIGUOUS_ASSOCIATIONS, property.toString())); - } else { - links.add(link); - } - } - } - } + return super.getLinksFor(object, existingLinks); } } diff --git a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java index f24f9944..276f176e 100644 --- a/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java +++ b/lightadmin-core/src/main/java/org/lightadmin/core/web/support/PersistentEntityWrapper.java @@ -21,7 +21,7 @@ * This class is moved out of {@link DynamicPersistentEntityResourceProcessor} * so that it can be used in other classes as well, like the {@link LightAdminLinkCollector}. * - * @author Gazi Rahman + * @author Gazi Rahman * */