1717
1818package org .openapitools .codegen .plugin ;
1919
20- import static org . apache . commons . lang3 . StringUtils . isNotEmpty ;
21- import static org . openapitools . codegen . config . CodegenConfiguratorUtils .* ;
22-
20+ import com . google . common . hash . Hashing ;
21+ import com . google . common . io . Files ;
22+ import io . swagger . parser . OpenAPIParser ;
2323import io .swagger .v3 .core .util .Json ;
2424import io .swagger .v3 .core .util .Yaml ;
2525import io .swagger .v3 .parser .OpenAPIResolver ;
2626import io .swagger .v3 .parser .OpenAPIV3Parser ;
27- import io .swagger .v3 .parser .core .models .AuthorizationValue ;
28- import java .io .File ;
29- import java .io .FileOutputStream ;
30- import java .io .IOException ;
31- import java .net .MalformedURLException ;
32- import java .net .URI ;
33- import java .net .URISyntaxException ;
34- import java .net .URL ;
35- import java .net .URLClassLoader ;
36- import java .net .URLConnection ;
37- import java .nio .channels .Channels ;
38- import java .nio .channels .FileChannel ;
39- import java .nio .channels .ReadableByteChannel ;
40- import java .nio .charset .StandardCharsets ;
41- import java .nio .file .Path ;
42- import java .text .MessageFormat ;
43- import java .util .ArrayList ;
44- import java .util .HashMap ;
45- import java .util .List ;
46- import java .util .Locale ;
47- import java .util .Map ;
48- import java .util .Set ;
49-
50- import com .google .common .io .ByteSource ;
51- import com .google .common .io .CharSource ;
5227import io .swagger .v3 .parser .core .models .ParseOptions ;
53- import io .swagger .v3 .parser .util .ClasspathHelper ;
5428import lombok .Setter ;
5529import org .apache .commons .io .FileUtils ;
5630import org .apache .commons .io .FilenameUtils ;
5933import org .apache .maven .plugin .AbstractMojo ;
6034import org .apache .maven .plugin .MojoExecution ;
6135import org .apache .maven .plugin .MojoExecutionException ;
62- import org .apache .maven .plugins .annotations .Component ;
63- import org .apache .maven .plugins .annotations .LifecyclePhase ;
64- import org .apache .maven .plugins .annotations .Mojo ;
65- import org .apache .maven .plugins .annotations .Parameter ;
66- import org .apache .maven .plugins .annotations .ResolutionScope ;
36+ import org .apache .maven .plugins .annotations .*;
6737import org .apache .maven .project .MavenProject ;
68-
6938import org .apache .maven .project .MavenProjectHelper ;
70- import org .openapitools .codegen .CliOption ;
71- import org .openapitools .codegen .ClientOptInput ;
72- import org .openapitools .codegen .CodegenConfig ;
73- import org .openapitools .codegen .CodegenConstants ;
74- import org .openapitools .codegen .DefaultGenerator ;
75- import org .openapitools .codegen .auth .AuthParser ;
39+ import org .openapitools .codegen .*;
7640import org .openapitools .codegen .config .CodegenConfigurator ;
7741import org .openapitools .codegen .config .GlobalSettings ;
7842import org .openapitools .codegen .config .MergedSpecBuilder ;
79- import org .sonatype .plexus .build .incremental .BuildContext ;
80- import org .sonatype .plexus .build .incremental .DefaultBuildContext ;
8143import org .slf4j .Logger ;
8244import org .slf4j .LoggerFactory ;
45+ import org .sonatype .plexus .build .incremental .BuildContext ;
46+ import org .sonatype .plexus .build .incremental .DefaultBuildContext ;
8347
84- import com .google .common .hash .Hashing ;
85- import com .google .common .io .Files ;
48+ import java .io .File ;
49+ import java .io .IOException ;
50+ import java .net .*;
51+ import java .nio .charset .StandardCharsets ;
52+ import java .nio .file .Path ;
53+ import java .text .MessageFormat ;
54+ import java .util .*;
55+
56+ import static org .apache .commons .lang3 .StringUtils .isNotEmpty ;
57+ import static org .openapitools .codegen .config .CodegenConfiguratorUtils .*;
8658
8759/**
8860 * Goal which generates client/server code from a OpenAPI json/yaml definition.
@@ -609,19 +581,11 @@ public void execute() throws MojoExecutionException {
609581 }
610582
611583 if (Boolean .TRUE .equals (skipIfSpecIsUnchanged )) {
612- File storedInputSpecHashFile = getHashFile (inputSpecFile );
584+ final File storedInputSpecHashFile = getHashFile (inputSpecFile );
613585 if (storedInputSpecHashFile .exists ()) {
614- String inputSpecHash = null ;
615- try {
616- inputSpecHash = calculateInputSpecHash (inputSpecFile );
617- } catch (IOException ex ) {
618- ex .printStackTrace ();
619- }
620- @ SuppressWarnings ("UnstableApiUsage" )
621586 String storedInputSpecHash = Files .asCharSource (storedInputSpecHashFile , StandardCharsets .UTF_8 ).read ();
622- if (storedInputSpecHash .equals (inputSpecHash )) {
623- getLog ().info (
624- "Code generation is skipped because input was unchanged" );
587+ if (storedInputSpecHash .equals (calculateInputSpecHash (inputSpec ))) {
588+ getLog ().info ("Code generation is skipped because input was unchanged" );
625589 return ;
626590 }
627591 }
@@ -1010,17 +974,15 @@ public void execute() throws MojoExecutionException {
1010974
1011975 // Store a checksum of the input spec
1012976 File storedInputSpecHashFile = getHashFile (inputSpecFile );
1013- String inputSpecHash = calculateInputSpecHash (inputSpecFile );
1014-
1015977 if (storedInputSpecHashFile .getParent () != null && !new File (storedInputSpecHashFile .getParent ()).exists ()) {
1016978 File parent = new File (storedInputSpecHashFile .getParent ());
1017979 if (!parent .mkdirs ()) {
1018980 throw new RuntimeException ("Failed to create the folder " + parent .getAbsolutePath () +
1019981 " to store the checksum of the input spec." );
1020982 }
1021983 }
1022- Files .asCharSink (storedInputSpecHashFile , StandardCharsets .UTF_8 ).write (inputSpecHash );
1023984
985+ Files .asCharSink (storedInputSpecHashFile , StandardCharsets .UTF_8 ).write (calculateInputSpecHash (inputSpec ));
1024986 } catch (Exception e ) {
1025987 // Maven logs exceptions thrown by plugins only if invoked with -e
1026988 // I find it annoying to jump through hoops to get basic diagnostic information,
@@ -1035,45 +997,21 @@ public void execute() throws MojoExecutionException {
1035997 }
1036998
1037999 /**
1038- * Calculate openapi specification file hash. If specification is hosted on remote resource it is downloaded first
1000+ * Calculate an SHA256 hash for the openapi specification.
1001+ * If the specification is hosted on a remote resource it is downloaded first.
10391002 *
1040- * @param inputSpecFile - Openapi specification input file to calculate its hash.
1041- * Does not take into account if input spec is hosted on remote resource
1042- * @return openapi specification file hash
1043- * @throws IOException
1003+ * @param inputSpec - Openapi specification input file. Can denote a URL or file path.
1004+ * @return openapi specification hash
10441005 */
1045- private String calculateInputSpecHash (File inputSpecFile ) throws IOException {
1046-
1047- URL inputSpecRemoteUrl = inputSpecRemoteUrl ();
1048-
1049- File inputSpecTempFile = inputSpecFile ;
1050-
1051- if (inputSpecRemoteUrl != null ) {
1052- inputSpecTempFile = java .nio .file .Files .createTempFile ("openapi-spec" , ".tmp" ).toFile ();
1053-
1054- URLConnection conn = inputSpecRemoteUrl .openConnection ();
1055- if (isNotEmpty (auth )) {
1056- List <AuthorizationValue > authList = AuthParser .parse (auth );
1057- for (AuthorizationValue a : authList ) {
1058- conn .setRequestProperty (a .getKeyName (), a .getValue ());
1059- }
1060- }
1061- try (ReadableByteChannel readableByteChannel = Channels .newChannel (conn .getInputStream ())) {
1062- FileChannel fileChannel ;
1063- try (FileOutputStream fileOutputStream = new FileOutputStream (inputSpecTempFile )) {
1064- fileChannel = fileOutputStream .getChannel ();
1065- fileChannel .transferFrom (readableByteChannel , 0 , Long .MAX_VALUE );
1066- }
1067- }
1068- }
1069-
1070- ByteSource inputSpecByteSource =
1071- inputSpecTempFile .exists ()
1072- ? Files .asByteSource (inputSpecTempFile )
1073- : CharSource .wrap (ClasspathHelper .loadFileFromClasspath (inputSpecTempFile .toString ().replaceAll ("\\ \\ " ,"/" )))
1074- .asByteSource (StandardCharsets .UTF_8 );
1075-
1076- return inputSpecByteSource .hash (Hashing .sha256 ()).toString ();
1006+ private String calculateInputSpecHash (String inputSpec ) {
1007+ final ParseOptions parseOptions = new ParseOptions ();
1008+ parseOptions .setResolve (true );
1009+
1010+ final URL remoteUrl = inputSpecRemoteUrl ();
1011+ return Hashing .sha256 ().hashBytes (
1012+ new OpenAPIParser ().readLocation (remoteUrl == null ? inputSpec : remoteUrl .toString (), null , parseOptions )
1013+ .getOpenAPI ().toString ().getBytes (StandardCharsets .UTF_8 )
1014+ ).toString ();
10771015 }
10781016
10791017 /**
0 commit comments