From d9d134cfc1ef3da725fa71abdf4a4c385e8ecb36 Mon Sep 17 00:00:00 2001 From: Schneider Roland Date: Fri, 20 Sep 2024 16:57:55 +0200 Subject: [PATCH] inital commit --- .gitignore | 40 ++++++++ pom.xml | 91 +++++++++++++++++++ src/main/java/at/ucs/magnolia/util/App.java | 13 +++ .../BootstrapUpdateYamlsWithProperties.java | 42 +++++++++ .../SimpleMagnoliaModuleVersionHandler.java | 53 +++++++++++ .../simpleUpdate/SimpleModuleUpdate.java | 38 ++++++++ .../simpleUpdate/UcsBootstrapUtil.java | 60 ++++++++++++ .../util/bootstrap/task/LoggingTask.java | 20 ++++ .../MagnoliaPropertyResolver.java | 30 ++++++ 9 files changed, 387 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/at/ucs/magnolia/util/App.java create mode 100644 src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/BootstrapUpdateYamlsWithProperties.java create mode 100644 src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleMagnoliaModuleVersionHandler.java create mode 100644 src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleModuleUpdate.java create mode 100644 src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/UcsBootstrapUtil.java create mode 100644 src/main/java/at/ucs/magnolia/util/bootstrap/task/LoggingTask.java create mode 100644 src/main/java/at/ucs/magnolia/util/configuration/MagnoliaPropertyResolver.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30ef8ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store + +.idea \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3d79981 --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + 4.0.0 + + at.ucs.magnolia.util + ucs-magnolia-utils + 1.0-SNAPSHOT + jar + + ucs-magnolia-utils + http://maven.apache.org + + + 17 + UTF-8 + 6.2.46 + 1.18.34 + + + + + + ucs.repo + http://192.168.1.229:8080/nexus/content/repositories/thirdparty/ + + + + + + magnolia.public + https://nexus.magnolia-cms.com/content/groups/public + + true + + + + vaadin-addons + https://maven.vaadin.com/vaadin-addons + + + + + + + info.magnolia.bundle + magnolia-bundle-parent + ${magnoliaBundleVersion} + pom + import + + + + + + + + info.magnolia + magnolia-core + + + org.projectlombok + lombok + ${version.lombok} + provided + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + ${javaVersion} + ${javaVersion} + + + org.projectlombok + lombok + ${version.lombok} + + + + + + + + diff --git a/src/main/java/at/ucs/magnolia/util/App.java b/src/main/java/at/ucs/magnolia/util/App.java new file mode 100644 index 0000000..658d84a --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/App.java @@ -0,0 +1,13 @@ +package at.ucs.magnolia.util; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/BootstrapUpdateYamlsWithProperties.java b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/BootstrapUpdateYamlsWithProperties.java new file mode 100644 index 0000000..1e29567 --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/BootstrapUpdateYamlsWithProperties.java @@ -0,0 +1,42 @@ +package at.ucs.magnolia.util.bootstrap.simpleUpdate; + +import info.magnolia.cms.util.ClasspathResourcesUtil; +import info.magnolia.module.InstallContext; +import info.magnolia.module.delta.BootstrapResourcesTask; + +import javax.jcr.RepositoryException; +import java.io.IOException; +import java.util.Arrays; + +/** + * This task bootstraps all yamls of update-yamls in a specific version and replaces magnolia property placeholder. + */ +public class BootstrapUpdateYamlsWithProperties extends BootstrapResourcesTask { + private final String version; + + public BootstrapUpdateYamlsWithProperties(String name, String description, String version) { + super(name, description); + this.version = version; + } + + @Override + protected void bootstrap(InstallContext installContext, int importUUIDBehavior) throws IOException, RepositoryException { + // In the original Task super.bootstrap is called, but since we want to call our own BootstrapUtil + // we have to use code called in the super class explicitly + String[] resourcesToBootstrap = ClasspathResourcesUtil.findResources(new ClasspathResourcesUtil.Filter() { + @Override + public boolean accept(final String name) { + return acceptResource(installContext, name); + } + }); + resourcesToBootstrap = filterResourcesToBootstrap(resourcesToBootstrap); + UcsBootstrapUtil.bootstrap(resourcesToBootstrap, importUUIDBehavior); + } + + private String[] filterResourcesToBootstrap(String[] resourcesToBootstrap) { + return Arrays.stream(resourcesToBootstrap) + .filter(s -> s.startsWith("/update-yamls/" + version+"/")) + .toArray(String[]::new); + } + +} diff --git a/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleMagnoliaModuleVersionHandler.java b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleMagnoliaModuleVersionHandler.java new file mode 100644 index 0000000..789f232 --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleMagnoliaModuleVersionHandler.java @@ -0,0 +1,53 @@ +package at.ucs.magnolia.util.bootstrap.simpleUpdate; + +import info.magnolia.module.DefaultModuleVersionHandler; +import info.magnolia.module.InstallContext; +import info.magnolia.module.delta.DeltaBuilder; +import info.magnolia.module.delta.Task; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * This class is optional and lets you manage the versions of your module, + * by registering "deltas" to maintain the module's configuration, or other type of content. + * If you don't need this, simply remove the reference to this class in the module descriptor xml. + * + * @see info.magnolia.module.DefaultModuleVersionHandler + * @see info.magnolia.module.ModuleVersionHandler + * @see info.magnolia.module.delta.Task + */ +public class SimpleMagnoliaModuleVersionHandler extends DefaultModuleVersionHandler { + + private final List updates = new ArrayList<>(); + + + public SimpleMagnoliaModuleVersionHandler() { + // define here all updates + } + + protected void registerUpdate(SimpleModuleUpdate update) { + this.updates.add(update); + register(DeltaBuilder.update(update.getVersion(), "") + .addTasks(update.getAllTasks()) + ); + } + + + protected List getUpdateTasks() { + return this.updates.stream().map(SimpleModuleUpdate::getAllTasks) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + @Override + protected List getExtraInstallTasks(InstallContext installContext) { + final List tasks = new ArrayList<>(); + tasks.addAll(super.getExtraInstallTasks(installContext)); + tasks.addAll(getUpdateTasks()); + return tasks; + } + +} diff --git a/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleModuleUpdate.java b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleModuleUpdate.java new file mode 100644 index 0000000..ef14114 --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/SimpleModuleUpdate.java @@ -0,0 +1,38 @@ +package at.ucs.magnolia.util.bootstrap.simpleUpdate; + +import at.ucs.magnolia.util.bootstrap.task.LoggingTask; +import info.magnolia.module.delta.Task; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +@Getter +@AllArgsConstructor +public abstract class SimpleModuleUpdate { + + private String version; + + public abstract List getUpdateTasks(); + + public List getUpdateTasksAfterBootstrap() { + return Collections.emptyList(); + } + + public List getAllTasks() { + return Stream.concat( + Stream.concat( + //Put tasks that should be executed before every update in here + Stream.of(new LoggingTask("updating to version: " + version, "")), + getUpdateTasks().stream()), + Stream.concat( + //Put tasks that should be executed after every update in here + Stream.of(new BootstrapUpdateYamlsWithProperties("Import bootstrap YAML folder", "Imports bootstrap YAML files from /update-yamls/" + version, version)), + getUpdateTasksAfterBootstrap().stream())) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/UcsBootstrapUtil.java b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/UcsBootstrapUtil.java new file mode 100644 index 0000000..67453f9 --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/bootstrap/simpleUpdate/UcsBootstrapUtil.java @@ -0,0 +1,60 @@ +package at.ucs.magnolia.util.bootstrap.simpleUpdate; + +import at.ucs.magnolia.util.configuration.MagnoliaPropertyResolver; +import info.magnolia.cms.util.StringLengthComparator; +import info.magnolia.importexport.BootstrapUtil; +import info.magnolia.init.MagnoliaConfigurationProperties; +import info.magnolia.objectfactory.Components; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +/** + * This class is exactly working like the original BootstrapUtil class of Magnolia, + * with the only difference, that it substitutes Magnolia Property placeholders + * with their actual value, since this is not implemented for bootstrap yamls by Magnolia + */ +public class UcsBootstrapUtil { + private static final Logger log = LoggerFactory.getLogger(BootstrapUtil.class); + + public static void bootstrap(String[] resourceNames, int importUUIDBehavior) throws IOException, RepositoryException { + // sort by length --> import parent node firstsubPath + List list = new ArrayList<>(Arrays.asList(resourceNames)); + if (list.contains(null)) { + throw new IllegalArgumentException("Resource names contain a entry that cannot be processed."); + } + + Collections.sort(list, new StringLengthComparator()); + + for (Iterator iter = list.iterator(); iter.hasNext(); ) { + bootstrap(iter.next(), null, importUUIDBehavior); + } + } + + public static void bootstrap(String resourceName, String subPath, int importUUIDBehavior) throws IOException, RepositoryException { + final InputStream stream = BootstrapUtil.class.getResourceAsStream(resourceName); + if (stream == null) { + throw new IOException("Can't find resource to bootstrap at " + resourceName); + } + + MagnoliaConfigurationProperties magnoliaConfiguration = Components.getComponent(MagnoliaConfigurationProperties.class); + InputStream resolvedStream = MagnoliaPropertyResolver.resolve(magnoliaConfiguration, stream); + // Verify if the node already exists and execute jcr import command + bootstrap(resourceName, subPath, resolvedStream, importUUIDBehavior); + } + + public static void bootstrap(String resourceName, String subPath, InputStream stream, int importUUIDBehavior) throws RepositoryException { + BootstrapUtil.bootstrap(resourceName, subPath, stream, importUUIDBehavior); + } + + public static void export(Node content, File directory) throws IOException, RepositoryException { + BootstrapUtil.export(content, directory); + } + +} diff --git a/src/main/java/at/ucs/magnolia/util/bootstrap/task/LoggingTask.java b/src/main/java/at/ucs/magnolia/util/bootstrap/task/LoggingTask.java new file mode 100644 index 0000000..7a5e992 --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/bootstrap/task/LoggingTask.java @@ -0,0 +1,20 @@ +package at.ucs.magnolia.util.bootstrap.task; + +import info.magnolia.module.InstallContext; +import info.magnolia.module.delta.AbstractTask; +import info.magnolia.module.delta.TaskExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LoggingTask extends AbstractTask { + + private static final Logger log = LoggerFactory.getLogger(LoggingTask.class.getName()); + public LoggingTask(String taskName, String taskDescription) { + super(taskName, taskDescription); + } + + @Override + public void execute(InstallContext installContext) throws TaskExecutionException { + log.info(getName()); + } +} diff --git a/src/main/java/at/ucs/magnolia/util/configuration/MagnoliaPropertyResolver.java b/src/main/java/at/ucs/magnolia/util/configuration/MagnoliaPropertyResolver.java new file mode 100644 index 0000000..c674aa9 --- /dev/null +++ b/src/main/java/at/ucs/magnolia/util/configuration/MagnoliaPropertyResolver.java @@ -0,0 +1,30 @@ +package at.ucs.magnolia.util.configuration; + +import info.magnolia.init.PropertySource; +import org.apache.commons.io.IOUtils; +import org.apache.commons.text.StringSubstitutor; + +import java.io.IOException; +import java.io.InputStream; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.text.StringSubstitutor.*; + +public class MagnoliaPropertyResolver { + private MagnoliaPropertyResolver() { + } + + public static InputStream resolve(PropertySource properties, InputStream in) { + try { + return IOUtils.toInputStream(replaceMagnoliaPlaceholders(properties, in), UTF_8); + } catch (IOException e) { + return null; + } + } + + private static String replaceMagnoliaPlaceholders(PropertySource properties, InputStream in) throws IOException { + StringSubstitutor substitutor = new StringSubstitutor(properties::getProperty, DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_ESCAPE); + return substitutor.replace(IOUtils.toString(in, UTF_8)); + } + +}