001/* 002 * JDrupes Builder 003 * Copyright (C) 2025 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.java; 020 021import com.google.common.flogger.FluentLogger; 022import java.nio.file.Path; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.List; 026import java.util.Locale; 027import java.util.Optional; 028import java.util.stream.Stream; 029import javax.tools.Diagnostic; 030import javax.tools.DiagnosticCollector; 031import javax.tools.JavaFileObject; 032import org.jdrupes.builder.api.Project; 033import org.jdrupes.builder.core.AbstractGenerator; 034 035/// A base class for generators that invoke java tools. 036/// 037public abstract class JavaTool extends AbstractGenerator { 038 039 private static final FluentLogger logger = FluentLogger.forEnclosingClass(); 040 private final List<String> options = new ArrayList<>(); 041 042 /// Instantiates a new java tool. 043 /// 044 /// @param project the project 045 /// 046 public JavaTool(Project project) { 047 super(project); 048 } 049 050 /// Adds the given options. 051 /// 052 /// @param options the options 053 /// @return the javadoc 054 /// 055 public JavaTool options(Stream<String> options) { 056 this.options.addAll(options.toList()); 057 return this; 058 } 059 060 /// Adds the given options. 061 /// 062 /// @param options the options 063 /// @return the javadoc 064 /// 065 public JavaTool options(String... options) { 066 this.options.addAll(Arrays.asList(options)); 067 return this; 068 } 069 070 /// Return the options. 071 /// 072 /// @return the stream 073 /// 074 public List<String> options() { 075 return options; 076 } 077 078 /// Find the argument for the given option. As some options are 079 /// allows in different styles, several names can be specified. 080 /// 081 /// @param names the names 082 /// @return the optional 083 /// 084 public Optional<String> optionArgument(String... names) { 085 var itr = options.iterator(); 086 if (itr.hasNext()) { 087 String opt = itr.next(); 088 if (Arrays.stream(names).anyMatch(opt::equals) && itr.hasNext()) { 089 return Optional.of(itr.next()); 090 } 091 } 092 return Optional.empty(); 093 } 094 095 /// Log diagnostic. 096 /// 097 /// @param diagnostic the diagnostic 098 /// 099 protected void logDiagnostic( 100 Diagnostic<? extends JavaFileObject> diagnostic) { 101 String msg; 102 if (diagnostic.getSource() == null) { 103 msg = diagnostic.getMessage(Locale.ENGLISH); 104 } else { 105 msg = String.format("%s:%d: %s", 106 project().rootProject().directory().relativize( 107 Path.of(diagnostic.getSource().toUri().getPath())), 108 diagnostic.getLineNumber(), 109 diagnostic.getMessage(null)); 110 } 111 switch (diagnostic.getKind()) { 112 case ERROR -> logger.atSevere().log(msg); 113 case WARNING -> logger.atWarning().log(msg); 114 case MANDATORY_WARNING -> logger.atWarning().log(msg); 115 default -> logger.atInfo().log(msg); 116 } 117 } 118 119 /// Log diagnostics. 120 /// 121 /// @param diagnostics the diagnostics 122 /// 123 protected void 124 logDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) { 125 for (var diagnostic : diagnostics.getDiagnostics()) { 126 logDiagnostic(diagnostic); 127 } 128 } 129}