001/* 002 * JDrupes Builder 003 * Copyright (C) 2026 Michael N. Lipp 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <https://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.builder.core; 020 021import java.nio.file.Path; 022import java.util.List; 023import java.util.Properties; 024import org.apache.commons.cli.CommandLine; 025import org.jdrupes.builder.api.ConfigurationException; 026import org.jdrupes.builder.api.Project; 027import org.jdrupes.builder.api.RootProject; 028 029/// The Class LauncherBase. 030/// 031@SuppressWarnings("PMD.UseUtilityClass") 032public class LauncherBase { 033 034 /// The ScopedValue for the build context. 035 @SuppressWarnings("PMD.FieldNamingConventions") 036 protected static final ScopedValue< 037 DefaultBuildContext> scopedBuildContext = ScopedValue.newInstance(); 038 039 static { 040 ScopedValueContext.add(scopedBuildContext); 041 } 042 043 /// Initializes a new launcher base. 044 /// 045 public LauncherBase() { 046 // Make javadoc happy 047 } 048 049 /// Returns the context. 050 /// 051 /// @return the optional 052 /// 053 public static DefaultBuildContext context() { 054 if (!scopedBuildContext.isBound()) { 055 throw new ConfigurationException() 056 .cause(new IllegalStateException()) 057 .message("BuildContext is not bound."); 058 } 059 return scopedBuildContext.get(); 060 } 061 062 /// Creates and initializes the root project and the sub projects. 063 /// Adds the sub projects to the root project automatically. This 064 /// method should be used if the launcher detects the sub projects 065 /// e.g. by reflection and the root project does not add its sub 066 /// projects itself. 067 /// 068 /// @param buildRoot the build root 069 /// @param rootProject the root project 070 /// @param subprojects the sub projects 071 /// @param jdbldProps the builder properties 072 /// @param commandLine the command line 073 /// @return the root project 074 /// 075 protected static AbstractRootProject createProjects( 076 Path buildRoot, Class<? extends RootProject> rootProject, 077 List<Class<? extends Project>> subprojects, 078 Properties jdbldProps, CommandLine commandLine) { 079 try { 080 return ScopedValue 081 .where(scopedBuildContext, 082 new DefaultBuildContext(buildRoot, jdbldProps, commandLine)) 083 .call(() -> { 084 var result = (AbstractRootProject) rootProject 085 .getConstructor().newInstance(); 086 result.unlockProviders(); 087 subprojects.forEach(result::project); 088 scopedBuildContext.get().buildProject().complete(result); 089 return result; 090 }); 091 } catch (SecurityException | NegativeArraySizeException 092 | IllegalArgumentException | ReflectiveOperationException e) { 093 throw new IllegalArgumentException(e); 094 } 095 } 096}