Add java bytecode class file version detection · codehaus-plexus/plexus-languages@5c06f1b (original) (raw)
``
1
`+
package org.codehaus.plexus.languages.java.version;
`
``
2
+
``
3
`+
import java.io.IOException;
`
``
4
`+
import java.io.UncheckedIOException;
`
``
5
`+
import java.nio.file.Files;
`
``
6
`+
import java.nio.file.Path;
`
``
7
+
``
8
`+
/*
`
``
9
`+
- Licensed to the Apache Software Foundation (ASF) under one
`
``
10
`+
- or more contributor license agreements. See the NOTICE file
`
``
11
`+
- distributed with this work for additional information
`
``
12
`+
- regarding copyright ownership. The ASF licenses this file
`
``
13
`+
- to you under the Apache License, Version 2.0 (the
`
``
14
`+
- "License"); you may not use this file except in compliance
`
``
15
`+
- with the License. You may obtain a copy of the License at
`
``
16
`+
`
``
17
`+
`
``
18
`+
`
``
19
`+
- Unless required by applicable law or agreed to in writing,
`
``
20
`+
- software distributed under the License is distributed on an
`
``
21
`+
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
`
``
22
`+
- KIND, either express or implied. See the License for the
`
``
23
`+
- specific language governing permissions and limitations
`
``
24
`+
- under the License.
`
``
25
`+
*/
`
``
26
+
``
27
`+
/**
`
``
28
`+
- Reads the bytecode of a Java class to detect the major, minor and Java
`
``
29
`+
- version that was compiled.
`
``
30
`+
`
``
31
`+
- @author Jorge Solórzano
`
``
32
`+
*/
`
``
33
`+
public final class JavaClassfileVersion {
`
``
34
+
``
35
`+
private final int major;
`
``
36
`+
private final int minor;
`
``
37
+
``
38
`+
JavaClassfileVersion(int major, int minor) {
`
``
39
`+
if (major < 45) {
`
``
40
`+
throw new IllegalArgumentException("Java class major version must be 45 or above.");
`
``
41
`+
}
`
``
42
`+
this.major = major;
`
``
43
`+
this.minor = minor;
`
``
44
`+
}
`
``
45
+
``
46
`+
/**
`
``
47
`+
- Reads the bytecode of a Java class file and returns the
`
``
48
`+
- {@link JavaClassfileVersion}.
`
``
49
`+
`
``
50
`+
- @param bytes {@code byte[]} of the Java class file
`
``
51
`+
- @return the {@link JavaClassfileVersion} of the byte array
`
``
52
`+
*/
`
``
53
`+
public static JavaClassfileVersion of(byte[] bytes) {
`
``
54
`+
return JavaClassfileVersionParser.of(bytes);
`
``
55
`+
}
`
``
56
+
``
57
`+
/**
`
``
58
`+
- Reads the bytecode of a Java class file and returns the
`
``
59
`+
- {@link JavaClassfileVersion}.
`
``
60
`+
`
``
61
`+
- @param path {@link Path} of the Java class file
`
``
62
`+
- @return the {@link JavaClassfileVersion} of the path java class
`
``
63
`+
*/
`
``
64
`+
public static JavaClassfileVersion of(Path path) {
`
``
65
`+
try {
`
``
66
`+
byte[] readAllBytes = Files.readAllBytes(path);
`
``
67
`+
return of(readAllBytes);
`
``
68
`+
} catch (IOException ex) {
`
``
69
`+
throw new UncheckedIOException(ex);
`
``
70
`+
}
`
``
71
`+
}
`
``
72
+
``
73
`+
/**
`
``
74
`+
- JavaVersion of the class file version detected.
`
``
75
`+
`
``
76
`+
- @return JavaVersion based on the major version of the class file.
`
``
77
`+
*/
`
``
78
`+
public JavaVersion javaVersion() {
`
``
79
`+
int javaVer = major - 44;
`
``
80
`+
String javaVersion = javaVer < 9 ? "1." + javaVer : Integer.toString(javaVer);
`
``
81
+
``
82
`+
return JavaVersion.parse(javaVersion);
`
``
83
`+
}
`
``
84
+
``
85
`+
/**
`
``
86
`+
- Returns the major version of the parsed classfile.
`
``
87
`+
`
``
88
`+
- @return the major classfile version
`
``
89
`+
*/
`
``
90
`+
public int majorVersion() {
`
``
91
`+
return major;
`
``
92
`+
}
`
``
93
+
``
94
`+
/**
`
``
95
`+
- Returns the minor version of the parsed classfile.
`
``
96
`+
`
``
97
`+
- @return the minor classfile version
`
``
98
`+
*/
`
``
99
`+
public int minorVersion() {
`
``
100
`+
return minor;
`
``
101
`+
}
`
``
102
+
``
103
`+
/**
`
``
104
`+
- Returns if the classfile use preview features.
`
``
105
`+
`
``
106
`+
- @return {@code true} if the classfile use preview features.
`
``
107
`+
*/
`
``
108
`+
public boolean isPreview() {
`
``
109
`+
return minor == 65535;
`
``
110
`+
}
`
``
111
+
``
112
`+
/**
`
``
113
`+
- Returns a String representation of the Java class file version, e.g.
`
``
114
`+
- {@code 65.0 (Java 21)}.
`
``
115
`+
`
``
116
`+
- @return String representation of the Java class file version
`
``
117
`+
*/
`
``
118
`+
@Override
`
``
119
`+
public String toString() {
`
``
120
`+
return major + "." + minor + " (Java " + javaVersion() + ")";
`
``
121
`+
}
`
``
122
+
``
123
`+
@Override
`
``
124
`+
public int hashCode() {
`
``
125
`+
final int prime = 31;
`
``
126
`+
int result = 1;
`
``
127
`+
result = prime * result + major;
`
``
128
`+
result = prime * result + minor;
`
``
129
`+
return result;
`
``
130
`+
}
`
``
131
+
``
132
`+
@Override
`
``
133
`+
public boolean equals(Object obj) {
`
``
134
`+
if (this == obj) return true;
`
``
135
`+
if (!(obj instanceof JavaClassfileVersion)) return false;
`
``
136
`+
JavaClassfileVersion other = (JavaClassfileVersion) obj;
`
``
137
`+
if (major != other.major) return false;
`
``
138
`+
if (minor != other.minor) return false;
`
``
139
`+
return true;
`
``
140
`+
}
`
``
141
`+
}
`