/* * Copyright 2015 Kevin Herron * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.digitalpetri.opcua.stack.core; import java.util.UUID; import com.digitalpetri.opcua.stack.core.types.builtin.ByteString; import com.digitalpetri.opcua.stack.core.types.builtin.DataValue; import com.digitalpetri.opcua.stack.core.types.builtin.DateTime; import com.digitalpetri.opcua.stack.core.types.builtin.DiagnosticInfo; import com.digitalpetri.opcua.stack.core.types.builtin.ExpandedNodeId; import com.digitalpetri.opcua.stack.core.types.builtin.ExtensionObject; import com.digitalpetri.opcua.stack.core.types.builtin.LocalizedText; import com.digitalpetri.opcua.stack.core.types.builtin.NodeId; import com.digitalpetri.opcua.stack.core.types.builtin.QualifiedName; import com.digitalpetri.opcua.stack.core.types.builtin.StatusCode; import com.digitalpetri.opcua.stack.core.types.builtin.Variant; import com.digitalpetri.opcua.stack.core.types.builtin.XmlElement; import com.digitalpetri.opcua.stack.core.types.builtin.unsigned.UByte; import com.digitalpetri.opcua.stack.core.types.builtin.unsigned.UInteger; import com.digitalpetri.opcua.stack.core.types.builtin.unsigned.ULong; import com.digitalpetri.opcua.stack.core.types.builtin.unsigned.UShort; import com.digitalpetri.opcua.stack.core.types.enumerated.IdType; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; public enum BuiltinDataType { Boolean(1, Boolean.class), SByte(2, Byte.class), Byte(3, UByte.class), Int16(4, Short.class), UInt16(5, UShort.class), Int32(6, Integer.class), UInt32(7, UInteger.class), Int64(8, Long.class), UInt64(9, ULong.class), Float(10, Float.class), Double(11, Double.class), String(12, String.class), DateTime(13, DateTime.class), Guid(14, UUID.class), ByteString(15, ByteString.class), XmlElement(16, XmlElement.class), NodeId(17, NodeId.class), ExpandedNodeId(18, ExpandedNodeId.class), StatusCode(19, StatusCode.class), QualifiedName(20, QualifiedName.class), LocalizedText(21, LocalizedText.class), ExtensionObject(22, ExtensionObject.class), DataValue(23, DataValue.class), Variant(24, Variant.class), DiagnosticInfo(25, DiagnosticInfo.class); private final int typeId; private final Class<?> backingClass; BuiltinDataType(int typeId, Class<?> backingClass) { this.typeId = typeId; this.backingClass = backingClass; } public int getTypeId() { return typeId; } public Class<?> getBackingClass() { return backingClass; } private static final BiMap<Integer, Class<?>> BackingClassesById; private static final BiMap<NodeId, Class<?>> BackingClassesByNodeId; static { ImmutableBiMap.Builder<Integer, Class<?>> builder = ImmutableBiMap.<Integer, Class<?>>builder(); ImmutableBiMap.Builder<NodeId, Class<?>> builder2 = ImmutableBiMap.<NodeId, Class<?>>builder(); for (BuiltinDataType dataType : values()) { builder.put(dataType.getTypeId(), dataType.getBackingClass()); builder2.put(new NodeId(0, dataType.getTypeId()), dataType.getBackingClass()); } BackingClassesById = builder.build(); BackingClassesByNodeId = builder2.build(); } /** * @param backingClass the backing {@link Class} of the builtin type. * @return the id of the builtin type backed by {@code backingClass}. */ public static int getBuiltinTypeId(Class<?> backingClass) { if (backingClass.isPrimitive()) { if (backingClass == boolean.class) backingClass = Boolean.class; else if (backingClass == byte.class) backingClass = Byte.class; else if (backingClass == short.class) backingClass = Short.class; else if (backingClass == int.class) backingClass = Integer.class; else if (backingClass == long.class) backingClass = Long.class; else if (backingClass == float.class) backingClass = Float.class; else if (backingClass == double.class) backingClass = Double.class; } return BackingClassesById.inverse().get(backingClass); } /** * @param typeId the id of the builtin type. * @return the {@link Class} backing the builtin type. */ public static Class<?> getBackingClass(int typeId) { return BackingClassesById.get(typeId); } public static Class<?> getBackingClass(NodeId typeId) { return BackingClassesByNodeId.get(typeId); } public static Class<?> getBackingClass(ExpandedNodeId typeId) { if (typeId.getNamespaceIndex().intValue() == 0 && typeId.getType() == IdType.Numeric) { Number id = (Number) typeId.getIdentifier(); return BackingClassesById.get(id.intValue()); } return null; } public static boolean isBuiltin(int typeId) { return BackingClassesById.containsKey(typeId); } public static boolean isBuiltin(NodeId typeId) { return BackingClassesByNodeId.containsKey(typeId); } public static boolean isBuiltin(ExpandedNodeId typeId) { return typeId.local().map(BackingClassesByNodeId::containsKey).orElse(false); } }