001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.lang3.arch;
018
019/**
020 * Represents a microprocessor and defines some properties like architecture and type.
021 *
022 * @since 3.6
023 */
024public class Processor {
025
026    /**
027     * Enumerates the architecture of a microprocessor.
028     * <p>
029     * The architecture represents the bit value of the microprocessor. The following architectures are defined:
030     * </p>
031     * <ul>
032     * <li>32-bit</li>
033     * <li>64-bit</li>
034     * <li>Unknown</li>
035     * </ul>
036     */
037    public enum Arch {
038
039        /**
040         * A 32-bit processor architecture.
041         */
042        BIT_32("32-bit"),
043
044        /**
045         * A 64-bit processor architecture.
046         */
047        BIT_64("64-bit"),
048
049        /**
050         * An unknown-bit processor architecture.
051         */
052        UNKNOWN("Unknown");
053
054        /**
055         * A label suitable for display.
056         */
057        private final String label;
058
059        Arch(final String label) {
060            this.label = label;
061        }
062
063        /**
064         * Gets the label suitable for display.
065         *
066         * @return The label.
067         */
068        public String getLabel() {
069            return label;
070        }
071    }
072
073    /**
074     * Enumerates types of a microprocessor.
075     * <p>
076     * The following types are defined:
077     * </p>
078     * <ul>
079     * <li>AArch64</li>
080     * <li>x86</li>
081     * <li>ia64</li>
082     * <li>PPC</li>
083     * <li>RISCV</li>
084     * <li>Unknown</li>
085     * </ul>
086     */
087    public enum Type {
088
089        /**
090         * ARM 64-bit.
091         *
092         * @since 3.13.0
093         */
094        AARCH_64("AArch64"),
095
096        /**
097         * Intel x86 series of instruction set architectures.
098         */
099        X86("x86"),
100
101        /**
102         * Intel Itanium 64-bit architecture.
103         */
104        IA_64("IA-64"),
105
106        /**
107         * Apple–IBM–Motorola PowerPC architecture.
108         */
109        PPC("PPC"),
110
111        /**
112         * RISC-V architecture.
113         *
114         * @since 3.14.0
115         */
116        RISC_V("RISC-V"),
117
118        /**
119         * Unknown architecture.
120         */
121        UNKNOWN("Unknown");
122
123        /**
124         * A label suitable for display.
125         */
126        private final String label;
127
128        Type(final String label) {
129            this.label = label;
130        }
131
132        /**
133         * Gets the label suitable for display.
134         *
135         * @return The label.
136         * @since 3.13.0
137         */
138        public String getLabel() {
139            return label;
140        }
141
142    }
143
144    private final Arch arch;
145    private final Type type;
146
147    /**
148     * Constructs a {@link Processor} object with the given
149     * parameters.
150     *
151     * @param arch The processor architecture.
152     * @param type The processor type.
153     */
154    public Processor(final Arch arch, final Type type) {
155        this.arch = arch;
156        this.type = type;
157    }
158
159    /**
160     * Gets the processor architecture as an {@link Arch} enum.
161     * The processor architecture defines, if the processor has
162     * a 32 or 64 bit architecture.
163     *
164     * @return A {@link Arch} enum.
165     */
166    public Arch getArch() {
167        return arch;
168    }
169
170    /**
171     * Gets the processor type as {@link Type} enum.
172     * The processor type defines, if the processor is for example
173     * an x86 or PPA.
174     *
175     * @return A {@link Type} enum.
176     */
177    public Type getType() {
178        return type;
179    }
180
181    /**
182     * Tests if {@link Processor} is 32 bit.
183     *
184     * @return {@code true}, if {@link Processor} is {@link Arch#BIT_32}, else {@code false}.
185     */
186    public boolean is32Bit() {
187        return Arch.BIT_32 == arch;
188    }
189
190    /**
191     * Tests if {@link Processor} is 64 bit.
192     *
193     * @return {@code true}, if {@link Processor} is {@link Arch#BIT_64}, else {@code false}.
194     */
195    public boolean is64Bit() {
196        return Arch.BIT_64 == arch;
197    }
198
199    /**
200     * Tests if {@link Processor} is type of Aarch64.
201     *
202     * @return {@code true}, if {@link Processor} is {@link Type#AARCH_64}, else {@code false}.
203     * @since 3.13.0
204     */
205    public boolean isAarch64() {
206        return Type.AARCH_64 == type;
207    }
208
209    /**
210     * Tests if {@link Processor} is type of Intel Itanium.
211     *
212     * @return {@code true}. if {@link Processor} is {@link Type#IA_64}, else {@code false}.
213     */
214    public boolean isIA64() {
215        return Type.IA_64 == type;
216    }
217
218    /**
219     * Tests if {@link Processor} is type of Power PC.
220     *
221     * @return {@code true}. if {@link Processor} is {@link Type#PPC}, else {@code false}.
222     */
223    public boolean isPPC() {
224        return Type.PPC == type;
225    }
226
227    /**
228     * Tests if {@link Processor} is type of RISC-V.
229     *
230     * @return {@code true}. if {@link Processor} is {@link Type#RISC_V}, else {@code false}.
231     * @since 3.14.0
232     */
233    public boolean isRISCV() {
234        return Type.RISC_V == type;
235    }
236
237    /**
238     * Tests if {@link Processor} is type of x86.
239     *
240     * @return {@code true}, if {@link Processor} is {@link Type#X86}, else {@code false}.
241     */
242    public boolean isX86() {
243        return Type.X86 == type;
244    }
245
246    @Override
247    public String toString() {
248        final StringBuilder builder = new StringBuilder();
249        builder.append(type.getLabel()).append(' ').append(arch.getLabel());
250        return builder.toString();
251    }
252
253}