diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..bc54a72
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,54 @@
+# Declare text files with unix file ending
+*.conf text eol=lf
+*.config text eol=lf
+*.css text eol=lf
+*.dtd text eol=lf
+*.esp text eol=lf
+*.ecma text eol=lf
+*.groovy text eol=lf
+*.hbrs text eol=lf
+*.hbs text eol=lf
+*.htm text eol=lf
+*.html text eol=lf
+*.java text eol=lf
+*.jpage text eol=lf
+*.js text eol=lf
+*.json text eol=lf
+*.jsp text eol=lf
+*.mustache text eol=lf
+*.tld text eol=lf
+*.launch text eol=lf
+*.log text eol=lf
+*.php text eol=lf
+*.pl text eol=lf
+*.project text eol=lf
+*.properties text eol=lf
+*.props text eol=lf
+*.sass text eol=lf
+*.scss text eol=lf
+*.sh text eol=lf
+*.shtm text eol=lf
+*.shtml text eol=lf
+*.sql text eol=lf
+*.svg text eol=lf
+*.txt text eol=lf
+*.vm text eol=lf
+*.xml text eol=lf
+*.xsd text eol=lf
+*.xsl text eol=lf
+*.xslt text eol=lf
+*.yml text eol=lf
+*.yaml text eol=lf
+
+
+# Declare windows-specific text files with windows file ending
+*.asp text eol=crlf
+*.asax text eol=crlf
+*.asa text eol=crlf
+*.aspx text eol=crlf
+*.bat text eol=crlf
+*.cmd text eol=crlf
+*.cs text eol=crlf
+*.csproj text eol=crlf
+*.reg text eol=crlf
+*.sln text eol=crlf
diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml
new file mode 100644
index 0000000..33879bd
--- /dev/null
+++ b/.github/workflows/maven-build.yml
@@ -0,0 +1,37 @@
+# Build validation
+
+name: Build
+
+on:
+ push:
+ branches-ignore:
+ - master
+ - experimental/**
+ pull_request:
+ types: [opened, synchronize, reopened]
+ branches-ignore:
+ - master
+ - experimental/**
+ workflow_dispatch:
+
+jobs:
+ build:
+
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ java: [11, 17]
+ os: [ubuntu-latest]
+ distribution: [temurin]
+
+ steps:
+ - name: Maven Build with SonarCloud
+ uses: wcm-io-devops/github-action-maven-build-sonar@v1
+ with:
+ os: ${{ matrix.os }}
+ java-version: ${{ matrix.java }}
+ maven-executable: ./mvnw
+ sonar-run-on-os: ubuntu-latest
+ sonar-run-on-java-version: 11
+ sonar-token: ${{ secrets.SONAR_TOKEN }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml
new file mode 100644
index 0000000..aef0ee4
--- /dev/null
+++ b/.github/workflows/maven-deploy.yml
@@ -0,0 +1,43 @@
+# Deploy snapshots to Sonatype OSS repository and deploy site to GitHub Pages
+
+name: Deploy
+
+on:
+ push:
+ branches:
+ - develop
+ workflow_dispatch:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Configure GIT
+ run: |
+ git config --global user.email "${{ secrets.GH_SITE_DEPLOY_EMAIL }}"
+ git config --global user.name "${{ secrets.GH_SITE_DEPLOY_NAME }}"
+
+ - name: Setup JDK
+ uses: actions/setup-java@v3
+ with:
+ distribution: temurin
+ java-version: 11
+ cache: maven
+
+ - name: Build, verify, deploy, generate site
+ env:
+ SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
+ SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
+ run: ./mvnw -s ./.maven-settings.xml -Pcontinuous-integration -B -U clean deploy site
+
+ - name: Stage and deploy site
+ run: >
+ ./mvnw -s ./.maven-settings.xml -Pcontinuous-integration -B site:stage scm-publish:publish-scm
+ -Dscmpublish.checkinComment="Maven site: ${{ github.repository }}"
+ -Dusername=${{ secrets.GH_SITE_DEPLOY_USERNAME }}
+ -Dpassword=${{ secrets.GH_SITE_DEPLOY_PAT }}
diff --git a/.github/workflows/release-from-tag.yml b/.github/workflows/release-from-tag.yml
new file mode 100644
index 0000000..e0e1724
--- /dev/null
+++ b/.github/workflows/release-from-tag.yml
@@ -0,0 +1,19 @@
+name: Release from Tag
+
+on:
+ push:
+ tags:
+ - '*'
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ncipollo/release-action@v1
+ with:
+ body: 'Changes: https://wcm.io/wcm/commons/changes-report.html'
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cb0de5f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+maven-eclipse.xml
+infinitest.filters
+
+node_modules/
+npm-debug.log
+
+.nodejs
+.project
+.classpath
+.settings
+.externalToolBuilders
+.pmd
+.eclipse-pmd
+.checkstyle
+.idea
+.vagrant
+*.iml
+.DS_Store
+*.retry
+.rubygems
+.sass-cache
+.rubygems-gem-maven-plugin
+*.sublime-*
+*nbactions*.xml
+.temp/
+.vlt
+.vlt-sync*
+.brackets.json
diff --git a/.maven-settings.xml b/.maven-settings.xml
new file mode 100644
index 0000000..fb12e79
--- /dev/null
+++ b/.maven-settings.xml
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+ default
+
+
+
+
+ central
+ https://repo1.maven.org/maven2/
+ default
+
+ true
+ never
+
+
+ false
+
+
+
+
+ oss-snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+ default
+
+ false
+
+
+ true
+ always
+
+
+
+
+ apache-snapshots
+ https://repository.apache.org/snapshots
+ default
+
+ false
+
+
+ true
+ always
+
+
+
+
+
+
+
+
+ central
+ https://repo1.maven.org/maven2/
+ default
+
+ true
+ never
+
+
+ false
+
+
+
+
+ oss-snapshots
+ https://oss.sonatype.org/content/repositories/snapshots
+ default
+
+ false
+
+
+ true
+ always
+
+
+
+
+ apache-snapshots
+ https://repository.apache.org/snapshots
+ default
+
+ false
+
+
+ true
+ always
+
+
+
+
+
+
+
+
+
+
+ default
+
+
+
+
+ ossrh
+ ${env.SONATYPE_USERNAME}
+ ${env.SONATYPE_PASSWORD}
+
+
+
+
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..c1dd12f
Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..8c79a83
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5c304d1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ 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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7cd81f1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+ WCM Commons
+======
+[![Build](https://github.com/wcm-io/io.wcm.wcm.commons/workflows/Build/badge.svg?branch=develop)](https://github.com/wcm-io/io.wcm.wcm.commons/actions?query=workflow%3ABuild+branch%3Adevelop)
+[![Maven Central](https://img.shields.io/maven-central/v/io.wcm/io.wcm.wcm.commons)](https://repo1.maven.org/maven2/io/wcm/io.wcm.wcm.commons/)
+[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=wcm-io_io.wcm.wcm.commons&metric=coverage)](https://sonarcloud.io/summary/new_code?id=wcm-io_io.wcm.wcm.commons)
+
+Common WCM utility and helper functions.
+
+Documentation: https://wcm.io/wcm/commons/
+Issues: https://github.com/wcm-io/io.wcm.wcm.commons/issues
+Wiki: https://wcm-io.atlassian.net/wiki/
+Continuous Integration: https://github.com/wcm-io/io.wcm.wcm.commons/actions
+Commercial support: https://wcm.io/commercial-support.html
+
+
+## Build from sources
+
+If you want to build wcm.io from sources make sure you have configured all [Maven Repositories](https://wcm.io/maven.html) in your settings.xml.
+
+See [Maven Settings](https://github.com/wcm-io/io.wcm.wcm.commons/blob/develop/.maven-settings.xml) for an example with a full configuration.
+
+Then you can build using
+
+```
+mvn clean install
+```
diff --git a/changes.xml b/changes.xml
index 8ed9874..0dee411 100644
--- a/changes.xml
+++ b/changes.xml
@@ -23,6 +23,21 @@
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd">
+
+
+ Switch to Java 11 as minimum version.
+
+
+ Switch to AEM 6.5.7 as minimum version.
+
+
+ Structure Element template: Switch to coralui3 client library.
+
+
+ Eliminate dependency to Guava.
+
+
+
\(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 0000000..8a15b7f
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 2a68682..579ca0e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,14 +24,14 @@
io.wcm
- io.wcm.wcm.parent
- 1.4.8
- ../parent/pom.xml
+ io.wcm.parent_toplevel
+ 2.2.0
+
io.wcm
io.wcm.wcm.commons
- 1.9.0
+ 1.10.0
jar
WCM Commons
@@ -39,9 +39,9 @@
${site.url}/${site.url.module.prefix}/
- scm:git:https://github.com/wcm-io/wcm-io-wcm.git
- scm:git:https://github.com/wcm-io/wcm-io-wcm.git
- https://github.com/wcm-io/wcm-io-wcm
+ scm:git:https://github.com/wcm-io/io.wcm.wcm.commons.git
+ scm:git:https://github.com/wcm-io/io.wcm.wcm.commons.git
+ https://github.com/wcm-io/io.wcm.wcm.commons
HEAD
@@ -49,7 +49,7 @@
wcm/commons
- 2021-10-28T13:13:19Z
+ 2023-04-19T11:25:26Z
@@ -102,7 +102,7 @@
io.wcm
io.wcm.testing.aem-mock.junit5
- 4.0.2
+ 5.0.0
test
@@ -124,15 +124,8 @@
- org.slf4j
- slf4j-api
- compile
-
-
-
-
- org.apache.geronimo.specs
- geronimo-annotation_1.3_spec
+ com.adobe.aem
+ uber-jar
provided
@@ -171,13 +164,30 @@
+
+ org.apache.maven.plugins
+ maven-site-plugin
+
+ ${site.deploy.url}
+
+
+
+
+ org.apache.maven.plugins
+ maven-scm-publish-plugin
+
+ ${site.url.module.prefix}
+ true
+
+
+
${site.deploy.id}
- ${site.deploy.url}/${site.url.module.prefix}
+ ${site.deploy.url}
diff --git a/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoImpl.java b/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoImpl.java
index 74a9500..a1b1a7d 100644
--- a/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoImpl.java
+++ b/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoImpl.java
@@ -38,7 +38,7 @@ class BundleInfoImpl implements BundleInfo {
private final String symbolicName;
private final Bundle bundle;
- private final Dictionary headers;
+ private final Dictionary headers;
private final BundleState state;
BundleInfoImpl(Bundle bundle) {
@@ -65,12 +65,12 @@ class BundleInfoImpl implements BundleInfo {
@Override
public @NotNull String getName() {
- return StringUtils.defaultString((String)headers.get(Constants.BUNDLE_NAME), getSymbolicName());
+ return StringUtils.defaultString(headers.get(Constants.BUNDLE_NAME), getSymbolicName());
}
@Override
public @NotNull String getVersion() {
- return StringUtils.defaultString((String)headers.get(Constants.BUNDLE_VERSION));
+ return StringUtils.defaultString(headers.get(Constants.BUNDLE_VERSION));
}
@Override
@@ -88,7 +88,7 @@ class BundleInfoImpl implements BundleInfo {
@Override
public boolean isFragment() {
- String fragmentHost = (String)headers.get(Constants.FRAGMENT_HOST);
+ String fragmentHost = headers.get(Constants.FRAGMENT_HOST);
return StringUtils.isNotBlank(fragmentHost);
}
diff --git a/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImpl.java b/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImpl.java
index a94feb2..9d8307e 100644
--- a/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImpl.java
+++ b/src/main/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImpl.java
@@ -50,7 +50,7 @@ void activate(BundleContext bc) {
public @NotNull Collection getBundles() {
return Arrays.stream(bundleContext.getBundles())
.map(bundle -> (BundleInfo)new BundleInfoImpl(bundle))
- .collect(Collectors.toCollection(() -> new TreeSet()));
+ .collect(Collectors.toCollection(TreeSet::new));
}
}
diff --git a/src/main/java/io/wcm/wcm/commons/caching/CacheHeader.java b/src/main/java/io/wcm/wcm/commons/caching/CacheHeader.java
index fafb763..a1f6381 100644
--- a/src/main/java/io/wcm/wcm/commons/caching/CacheHeader.java
+++ b/src/main/java/io/wcm/wcm/commons/caching/CacheHeader.java
@@ -19,7 +19,6 @@
*/
package io.wcm.wcm.commons.caching;
-import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -62,11 +61,13 @@ private CacheHeader() {
static final String HEADER_CACHE_CONTROL = "Cache-Control";
static final String HEADER_EXPIRES = "Expires";
static final String HEADER_DISPATCHER = "Dispatcher";
+ static final String NO_CACHE = "no-cache";
/**
* shared instance of the RFC1123 date format, must not be used directly but only using the synchronized {@link #formatDate(Date)} and
* {@link #parseDate(String)} methods
*/
+ @SuppressWarnings("java:S2885")
private static final DateFormat RFC1123_DATE_FORMAT = new SimpleDateFormat(RFC_1123_DATE_PATTERN, Locale.US);
static {
// all times are written and parsed in GMT
@@ -94,10 +95,9 @@ static synchronized Date parseDate(String pDateString) throws ParseException {
* @param response Response
* @return true if the method send a 304 redirect, so that the caller shouldn't write any output to the response
* stream
- * @throws IOException I/O exception
*/
public static boolean isNotModified(@NotNull Resource resource,
- @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws IOException {
+ @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) {
ResourceModificationDateProvider dateProvider = new ResourceModificationDateProvider(resource);
return isNotModified(dateProvider, request, response);
}
@@ -113,10 +113,9 @@ public static boolean isNotModified(@NotNull Resource resource,
* @param setExpiresHeader Set expires header to -1 to ensure the browser checks for a new version on every request.
* @return true if the method send a 304 redirect, so that the caller shouldn't write any output to the response
* stream
- * @throws IOException I/O exception
*/
public static boolean isNotModified(@NotNull Resource resource,
- @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response, boolean setExpiresHeader) throws IOException {
+ @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response, boolean setExpiresHeader) {
ResourceModificationDateProvider dateProvider = new ResourceModificationDateProvider(resource);
return isNotModified(dateProvider, request, response, setExpiresHeader);
}
@@ -134,10 +133,9 @@ public static boolean isNotModified(@NotNull Resource resource,
* @param response Response
* @return true if the method send a 304 redirect, so that the caller shouldn't write any output to the response
* stream
- * @throws IOException I/O exception
*/
public static boolean isNotModified(@NotNull ModificationDateProvider dateProvider,
- @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws IOException {
+ @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) {
boolean isAuthor = WCMMode.fromRequest(request) != WCMMode.DISABLED;
return isNotModified(dateProvider, request, response, isAuthor);
}
@@ -153,10 +151,9 @@ public static boolean isNotModified(@NotNull ModificationDateProvider dateProvid
* @param setExpiresHeader Set expires header to -1 to ensure the browser checks for a new version on every request.
* @return true if the method send a 304 redirect, so that the caller shouldn't write any output to the response
* stream
- * @throws IOException I/O exception
*/
public static boolean isNotModified(@NotNull ModificationDateProvider dateProvider,
- @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response, boolean setExpiresHeader) throws IOException {
+ @NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response, boolean setExpiresHeader) {
// assume the resource *was* modified until we know better
boolean isModified = true;
@@ -204,10 +201,10 @@ public static boolean isNotModified(@NotNull ModificationDateProvider dateProvid
* @param response Current response
*/
public static void setNonCachingHeaders(@NotNull HttpServletResponse response) {
- response.setHeader(HEADER_PRAGMA, "no-cache");
- response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
+ response.setHeader(HEADER_PRAGMA, NO_CACHE);
+ response.setHeader(HEADER_CACHE_CONTROL, NO_CACHE);
response.setHeader(HEADER_EXPIRES, "0");
- response.setHeader(HEADER_DISPATCHER, "no-cache");
+ response.setHeader(HEADER_DISPATCHER, NO_CACHE);
}
/**
diff --git a/src/main/java/io/wcm/wcm/commons/caching/ModificationDate.java b/src/main/java/io/wcm/wcm/commons/caching/ModificationDate.java
index 7022803..900c84d 100644
--- a/src/main/java/io/wcm/wcm/commons/caching/ModificationDate.java
+++ b/src/main/java/io/wcm/wcm/commons/caching/ModificationDate.java
@@ -82,7 +82,7 @@ private ModificationDate() {
return mostRecent(cqModified, resourceModified);
}
- @SuppressWarnings("null")
+ @SuppressWarnings({ "null", "java:S2589" }) // extra null checks for backward compatibility
private static Date getResourceMetadataModificationTime(Resource resource) {
ResourceMetadata metadata = resource.getResourceMetadata();
if (metadata != null) {
@@ -99,6 +99,7 @@ private static Date getResourceMetadataModificationTime(Resource resource) {
* @param resources multiple resources (typically jcr:content nodes of cq-pages or rendition resources)
* @return the most recent date (or null if none of the resources has a modification date)
*/
+ @SuppressWarnings("java:S2259") // array itself is marked as NotNull
public static @Nullable Date mostRecent(@Nullable Resource @NotNull... resources) {
Date[] dates = new Date[resources.length];
for (int i = 0; i < resources.length; i++) {
@@ -112,6 +113,7 @@ private static Date getResourceMetadataModificationTime(Resource resource) {
* @param pages multiple cq pages
* @return the most recent date (or null if none of the pages has a modification date)
*/
+ @SuppressWarnings("java:S2259") // array itself is marked as NotNull
public static @Nullable Date mostRecent(@Nullable Page @NotNull... pages) {
Date[] dates = new Date[pages.length];
for (int i = 0; i < pages.length; i++) {
diff --git a/src/main/java/io/wcm/wcm/commons/component/ComponentPropertyResolver.java b/src/main/java/io/wcm/wcm/commons/component/ComponentPropertyResolver.java
index f9566f4..d5d0a33 100644
--- a/src/main/java/io/wcm/wcm/commons/component/ComponentPropertyResolver.java
+++ b/src/main/java/io/wcm/wcm/commons/component/ComponentPropertyResolver.java
@@ -20,7 +20,9 @@
package io.wcm.wcm.commons.component;
import java.util.Collection;
+import java.util.Map;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
@@ -40,8 +42,6 @@
import com.day.cq.wcm.api.components.ComponentManager;
import com.day.cq.wcm.api.policies.ContentPolicy;
import com.day.cq.wcm.api.policies.ContentPolicyManager;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import io.wcm.sling.commons.adapter.AdaptTo;
@@ -189,7 +189,7 @@ private static boolean hasResourceType(@NotNull Resource resource) {
return StringUtils.isNotEmpty(resource.getResourceType());
}
- @SuppressWarnings("null")
+ @SuppressWarnings({ "null", "java:S2589" }) // extra null checks for backward compatibility
private static @Nullable Resource getResourceWithResourceType(@Nullable Resource resource) {
if (resource == null) {
return null;
@@ -370,6 +370,7 @@ public ComponentPropertyResolver contentPolicyResolution(@NotNull ComponentPrope
return result;
}
+ @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull")
private @Nullable Collection getContentPolicyResources(@NotNull String name) {
if (contentPolicyResolution == ComponentPropertyResolution.IGNORE || resource == null) {
return null;
@@ -388,7 +389,7 @@ public ComponentPropertyResolver contentPolicyResolution(@NotNull ComponentPrope
if (parent == null) {
return null;
}
- Collection children = ImmutableList.copyOf(parent.getChildren());
+ Collection children = IterableUtils.toList(parent.getChildren());
if (children.isEmpty()) {
return null;
}
@@ -419,7 +420,7 @@ public ComponentPropertyResolver contentPolicyResolution(@NotNull ComponentPrope
&& !initComponentsResourceResolverFailed) {
try {
componentsResourceResolver = resourceResolverFactory.getServiceResourceResolver(
- ImmutableMap.of(ResourceResolverFactory.SUBSERVICE, SERVICEUSER_SUBSERVICE));
+ Map.of(ResourceResolverFactory.SUBSERVICE, SERVICEUSER_SUBSERVICE));
}
catch (LoginException ex) {
initComponentsResourceResolverFailed = true;
diff --git a/src/main/java/io/wcm/wcm/commons/contenttype/FileExtension.java b/src/main/java/io/wcm/wcm/commons/contenttype/FileExtension.java
index 5d64ba9..30185f9 100644
--- a/src/main/java/io/wcm/wcm/commons/contenttype/FileExtension.java
+++ b/src/main/java/io/wcm/wcm/commons/contenttype/FileExtension.java
@@ -19,6 +19,7 @@
*/
package io.wcm.wcm.commons.contenttype;
+import java.util.Collections;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
@@ -26,8 +27,6 @@
import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ProviderType;
-import com.google.common.collect.ImmutableSet;
-
/**
* Frequently used file extensions.
*/
@@ -133,7 +132,7 @@ private FileExtension() {
/**
* all file extensions that will be displayed by an image tag
*/
- private static final Set IMAGE_FILE_EXTENSIONS = ImmutableSet.of(
+ private static final Set IMAGE_FILE_EXTENSIONS = Set.of(
GIF,
JPEG,
PNG,
@@ -143,7 +142,7 @@ private FileExtension() {
/**
* all file extensions that will be displayed as flash
*/
- private static final Set FLASH_FILE_EXTENSIONS = ImmutableSet.of(
+ private static final Set FLASH_FILE_EXTENSIONS = Set.of(
SWF
);
@@ -168,7 +167,7 @@ public static boolean isImage(@Nullable String fileExtension) {
*/
@Deprecated
public static @NotNull Set getImageFileExtensions() {
- return IMAGE_FILE_EXTENSIONS;
+ return Collections.unmodifiableSet(IMAGE_FILE_EXTENSIONS);
}
/**
@@ -191,7 +190,7 @@ public static boolean isFlash(@Nullable String fileExtension) {
*/
@Deprecated
public static @NotNull Set getFlashFileExtensions() {
- return FLASH_FILE_EXTENSIONS;
+ return Collections.unmodifiableSet(FLASH_FILE_EXTENSIONS);
}
}
diff --git a/src/main/java/io/wcm/wcm/commons/controller/VersionInfo.java b/src/main/java/io/wcm/wcm/commons/controller/VersionInfo.java
index 006bd9c..f29f009 100644
--- a/src/main/java/io/wcm/wcm/commons/controller/VersionInfo.java
+++ b/src/main/java/io/wcm/wcm/commons/controller/VersionInfo.java
@@ -93,8 +93,7 @@ private boolean matchesFilterPatterns(BundleInfo bundle, List filterPat
return true;
}
return filterPatterns.stream()
- .filter(pattern -> pattern.matcher(bundle.getSymbolicName()).matches())
- .findAny().isPresent();
+ .anyMatch(pattern -> pattern.matcher(bundle.getSymbolicName()).matches());
}
private Stream getFilterRegex() {
diff --git a/src/main/java/io/wcm/wcm/commons/util/RunMode.java b/src/main/java/io/wcm/wcm/commons/util/RunMode.java
index 2cb8f8b..391db1a 100644
--- a/src/main/java/io/wcm/wcm/commons/util/RunMode.java
+++ b/src/main/java/io/wcm/wcm/commons/util/RunMode.java
@@ -65,7 +65,7 @@ private RunMode() {
public static boolean is(Set runModes, String... expectedRunModes) {
if (runModes != null && expectedRunModes != null) {
for (String expectedRunMode : expectedRunModes) {
- if (runModes.contains(expectedRunMode)) {
+ if (expectedRunMode != null && runModes.contains(expectedRunMode)) {
return true;
}
}
@@ -133,19 +133,15 @@ public static boolean disableIfNoRunModeActive(Set runModes, String[] al
}
if (!isActive) {
if (log.isDebugEnabled()) {
- log.debug("Component '" + name + "' "
- + "disabled as none of its run modes (" + StringUtils.join(allowedRunModes, ",") + ") "
- + "are currently active (" + StringUtils.join(runModes, ",") + ")."
- );
+ log.debug("Component '{}' disabled as none of its run modes ({}) are currently active ({}).",
+ name, StringUtils.join(allowedRunModes, ","), StringUtils.join(runModes, ","));
}
componentContext.disableComponent(name);
result = true;
}
else if (log.isDebugEnabled()) {
- log.debug("Component '" + name + "' "
- + "enabled as at least one of its run modes (" + StringUtils.join(allowedRunModes, ",") + ") "
- + "are currently active (" + StringUtils.join(runModes, ",") + ")."
- );
+ log.debug("Component '{}' enabled as at least one of its run modes ({}) are currently active ({}).",
+ name, StringUtils.join(allowedRunModes, ","), StringUtils.join(runModes, ","));
}
return result;
diff --git a/src/main/java/io/wcm/wcm/commons/util/Template.java b/src/main/java/io/wcm/wcm/commons/util/Template.java
index ddb7b24..42fa2a5 100644
--- a/src/main/java/io/wcm/wcm/commons/util/Template.java
+++ b/src/main/java/io/wcm/wcm/commons/util/Template.java
@@ -35,7 +35,7 @@
* Template utility methods
*/
@ProviderType
-@SuppressWarnings("null")
+@SuppressWarnings({ "null", "java:S2589" }) // extra null checks for backward compatibility
public final class Template {
static final Pattern TEMPLATE_PATH_PATTERN = Pattern.compile("^/(apps|libs)/(.+)/templates(/.*)?/([^/]+)$");
diff --git a/src/main/webapp/app-root/components/page/structureElement/structureElement.html b/src/main/webapp/app-root/components/page/structureElement/structureElement.html
index da218df..ad3be4b 100644
--- a/src/main/webapp/app-root/components/page/structureElement/structureElement.html
+++ b/src/main/webapp/app-root/components/page/structureElement/structureElement.html
@@ -5,7 +5,7 @@
${currentPage.title}
-
+
diff --git a/src/site/markdown/components.md b/src/site/markdown/components.md
index 268fec1..8f28fe6 100644
--- a/src/site/markdown/components.md
+++ b/src/site/markdown/components.md
@@ -1,7 +1,7 @@
-## Sightly components
+## Sightly components (deprecated)
-### wcmInit
+### wcmInit (deprecated)
On the author instance, this component initalizes the edit mode and loads all required client libs. Supports both Touch UI and Classic UI.
@@ -41,7 +41,7 @@ Markup for subcomponent:
```
-### page
+### page (deprecated)
Base page component which defines a simplified page properties dialog with only basic features.
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index facca6e..671642e 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -2,7 +2,7 @@
Common WCM utility and helper functions.
-[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.wcm.commons/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.wcm.commons)
+[![Maven Central](https://img.shields.io/maven-central/v/io.wcm/io.wcm.wcm.commons)](https://repo1.maven.org/maven2/io/wcm/io.wcm.wcm.commons/)
### Documentation
@@ -26,7 +26,8 @@ The WCM Commons library contains:
|WCM Commons version |AEM version supported
|--------------------|----------------------
-|1.8.x or higher |AEM 6.4+, AEMaaCS
+|1.10.x or higher |AEM 6.5.7+, AEMaaCS
+|1.8.x - 1.9.x |AEM 6.4+, AEMaaCS
|1.6.x - 1.7.x |AEM 6.3+
|1.3.x - 1.5.x |AEM 6.2+
|1.0.x - 1.2.x |AEM 6.1+
@@ -38,10 +39,14 @@ The WCM Commons library contains:
To use this module you have to deploy also:
|---|---|---|
-| [wcm.io Sling Commons](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.sling.commons) | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.sling.commons/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.sling.commons) |
-| [wcm.io AEM Sling Models Extensions](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.sling.models) | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.sling.models/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.wcm/io.wcm.sling.models) |
+| [wcm.io Sling Commons](https://repo1.maven.org/maven2/io/wcm/io.wcm.sling.commons/) | [![Maven Central](https://img.shields.io/maven-central/v/io.wcm/io.wcm.sling.commons)](https://repo1.maven.org/maven2/io/wcm/io.wcm.sling.commons/) |
+| [wcm.io AEM Sling Models Extensions](https://repo1.maven.org/maven2/io/wcm/io.wcm.sling.models/) | [![Maven Central](https://img.shields.io/maven-central/v/io.wcm/io.wcm.sling.models)](https://repo1.maven.org/maven2/io/wcm/io.wcm.sling.models/) |
+### GitHub Repository
+
+Sources: https://github.com/wcm-io/io.wcm.wcm.commons
+
[components]: components.html
[configuration]: configuration.html
diff --git a/src/site/site.xml b/src/site/site.xml
new file mode 100644
index 0000000..810e993
--- /dev/null
+++ b/src/site/site.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImplTest.java b/src/test/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImplTest.java
index 47585d1..7945c25 100644
--- a/src/test/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImplTest.java
+++ b/src/test/java/io/wcm/wcm/commons/bundleinfo/impl/BundleInfoServiceImplTest.java
@@ -43,8 +43,6 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import com.google.common.collect.ImmutableList;
-
import io.wcm.wcm.commons.bundleinfo.BundleInfo;
import io.wcm.wcm.commons.bundleinfo.BundleInfoService;
import io.wcm.wcm.commons.bundleinfo.BundleState;
@@ -79,7 +77,7 @@ void testBundles() {
bundle("minimalBundle2", BundleState.RESOLVED),
bundle("fragmentBundle3", BundleState.INSTALLED, BUNDLE_NAME, "Fragment 1", BUNDLE_VERSION, "1.0", FRAGMENT_HOST, "fragment"));
- List result = ImmutableList.copyOf(underTest.getBundles());
+ List result = List.copyOf(underTest.getBundles());
assertEquals(3, result.size());
BundleInfo bundle1 = result.get(0);
diff --git a/src/test/java/io/wcm/wcm/commons/component/AbstractComponentPropertyResolverResourcesTest.java b/src/test/java/io/wcm/wcm/commons/component/AbstractComponentPropertyResolverResourcesTest.java
index ebfe5f2..7e652c6 100644
--- a/src/test/java/io/wcm/wcm/commons/component/AbstractComponentPropertyResolverResourcesTest.java
+++ b/src/test/java/io/wcm/wcm/commons/component/AbstractComponentPropertyResolverResourcesTest.java
@@ -37,9 +37,8 @@
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.components.ComponentContext;
import com.day.cq.wcm.commons.WCMUtils;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSortedMap;
+import io.wcm.sling.commons.resource.ImmutableValueMap;
import io.wcm.testing.mock.aem.junit5.AemContext;
abstract class AbstractComponentPropertyResolverResourcesTest {
@@ -196,14 +195,14 @@ void testPageAndComponent_Inheritance() {
@Test
void testPageAndPolicyAndComponent_Inheritance_ComponentContext() {
context.contentPolicyMapping("app1/components/comp1",
- "node2", ImmutableSortedMap.of(
- "item2", ImmutableMap.of()),
- "node5", ImmutableSortedMap.of(
- "item5", ImmutableMap.of()));
+ "node2", ImmutableValueMap.of(
+ "item2", ImmutableValueMap.of()),
+ "node5", ImmutableValueMap.of(
+ "item5", ImmutableValueMap.of()));
context.contentPolicyMapping("app1/components/comp2",
- "node6", ImmutableSortedMap.of(
- "item6", ImmutableMap.of(),
- "item7", ImmutableMap.of()));
+ "node6", ImmutableValueMap.of(
+ "item6", ImmutableValueMap.of(),
+ "item7", ImmutableValueMap.of()));
Page page1 = context.create().page("/content/page1");
context.create().resource(page1, "node1/item1");
@@ -243,9 +242,9 @@ void testPageAndPolicyAndComponent_Inheritance_ComponentContext() {
@Test
void testContentPolicy() {
context.contentPolicyMapping("app1/components/comp1",
- "node1", ImmutableSortedMap.of(
- "item1", ImmutableMap.of(),
- "item2", ImmutableMap.of()));
+ "node1", ImmutableValueMap.of(
+ "item1", ImmutableValueMap.of(),
+ "item2", ImmutableValueMap.of()));
Page page = context.create().page("/content/page1");
Resource resource = context.create().resource(page, "r1",
diff --git a/src/test/java/io/wcm/wcm/commons/controller/VersionInfoTest.java b/src/test/java/io/wcm/wcm/commons/controller/VersionInfoTest.java
index 1d9eb03..88774de 100644
--- a/src/test/java/io/wcm/wcm/commons/controller/VersionInfoTest.java
+++ b/src/test/java/io/wcm/wcm/commons/controller/VersionInfoTest.java
@@ -33,8 +33,6 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import com.google.common.collect.ImmutableList;
-
import io.wcm.sling.commons.adapter.AdaptTo;
import io.wcm.sling.commons.resource.ImmutableValueMap;
import io.wcm.testing.mock.aem.junit5.AemContext;
@@ -59,7 +57,7 @@ void setUp() {
context.registerService(BundleInfoService.class, bundleInfoService);
context.registerInjectActivateService(new ComponentPropertyResolverFactoryImpl());
- List bundles = ImmutableList.of(
+ List bundles = List.of(
bundle("aaa.bundle1"),
bundle("aaa.bundle2"),
bundle("bbb.bundle3"));
@@ -111,7 +109,7 @@ private BundleInfo bundle(String symbolicName) {
}
private void assertBundles(String... expectedBundles) {
- List expected = ImmutableList.copyOf(expectedBundles);
+ List expected = List.of(expectedBundles);
VersionInfo underTest = AdaptTo.notNull(context.request(), VersionInfo.class);
List actual = underTest.getBundles().stream()
diff --git a/src/test/java/io/wcm/wcm/commons/util/RunModeTest.java b/src/test/java/io/wcm/wcm/commons/util/RunModeTest.java
index 4315153..92973d7 100644
--- a/src/test/java/io/wcm/wcm/commons/util/RunModeTest.java
+++ b/src/test/java/io/wcm/wcm/commons/util/RunModeTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.Collections;
import java.util.Hashtable;
import java.util.Set;
@@ -39,15 +40,13 @@
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
-import com.google.common.collect.ImmutableSet;
-
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@SuppressWarnings("deprecation")
class RunModeTest {
- private static final Set AUTHOR_RUNMODES = ImmutableSet.of(RunMode.AUTHOR);
- private static final Set PUBLISH_RUNMODES = ImmutableSet.of(RunMode.PUBLISH, "anotherRunMode");
+ private static final Set AUTHOR_RUNMODES = Set.of(RunMode.AUTHOR);
+ private static final Set PUBLISH_RUNMODES = Set.of(RunMode.PUBLISH, "anotherRunMode");
@Mock
private ComponentContext componentContext;
@@ -64,7 +63,7 @@ void setUp() {
@Test
void testIs() {
- Set runModes = ImmutableSet.of("mode1", "mode2");
+ Set runModes = Set.of("mode1", "mode2");
assertTrue(RunMode.is(runModes, "mode1"));
assertTrue(RunMode.is(runModes, "mode2"));
assertFalse(RunMode.is(runModes, "mode3"));
@@ -72,7 +71,7 @@ void testIs() {
@Test
void testIsEmptySet() {
- Set runModes = ImmutableSet.of();
+ Set runModes = Collections.emptySet();
assertFalse(RunMode.is(runModes, "mode1"));
assertFalse(RunMode.is(runModes, "mode2"));
assertFalse(RunMode.is(runModes, "mode3"));
@@ -88,7 +87,7 @@ void testIsNullSet() {
@Test
void testIsInvalidParams() {
- Set runModes = ImmutableSet.of("mode1", "mode2");
+ Set runModes = Set.of("mode1", "mode2");
assertFalse(RunMode.is(runModes));
assertFalse(RunMode.is(runModes, (String[])null));
assertFalse(RunMode.is(runModes, (String)null));
@@ -96,13 +95,13 @@ void testIsInvalidParams() {
@Test
void testIsAuthor() {
- Set runModes = ImmutableSet.of("mode1", "author");
+ Set runModes = Set.of("mode1", "author");
assertTrue(RunMode.isAuthor(runModes));
}
@Test
void testIsPublish() {
- Set runModes = ImmutableSet.of("publish");
+ Set runModes = Set.of("publish");
assertTrue(RunMode.isPublish(runModes));
}