47 changed files with 456 additions and 856 deletions
@ -1,45 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
import org.hibernate.type.AbstractSingleColumnStandardBasicType; |
|||
import org.hibernate.usertype.DynamicParameterizedType; |
|||
|
|||
import java.util.Properties; |
|||
|
|||
public abstract class AbstractArrayType<T> |
|||
extends AbstractSingleColumnStandardBasicType<T> |
|||
implements DynamicParameterizedType { |
|||
|
|||
public static final String SQL_ARRAY_TYPE = "sql_array_type"; |
|||
|
|||
public AbstractArrayType(AbstractArrayTypeDescriptor<T> arrayTypeDescriptor) { |
|||
super( |
|||
ArraySqlTypeDescriptor.INSTANCE, |
|||
arrayTypeDescriptor |
|||
); |
|||
} |
|||
|
|||
@Override |
|||
protected boolean registerUnderJavaType() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public void setParameterValues(Properties parameters) { |
|||
((AbstractArrayTypeDescriptor) getJavaTypeDescriptor()).setParameterValues(parameters); |
|||
} |
|||
} |
|||
@ -1,119 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
import org.hibernate.HibernateException; |
|||
import org.hibernate.type.descriptor.WrapperOptions; |
|||
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; |
|||
import org.hibernate.type.descriptor.java.MutabilityPlan; |
|||
import org.hibernate.type.descriptor.java.MutableMutabilityPlan; |
|||
import org.hibernate.usertype.DynamicParameterizedType; |
|||
|
|||
import java.sql.Array; |
|||
import java.sql.SQLException; |
|||
import java.util.Arrays; |
|||
import java.util.Properties; |
|||
|
|||
import static org.thingsboard.server.dao.util.mapping.AbstractArrayType.SQL_ARRAY_TYPE; |
|||
|
|||
public abstract class AbstractArrayTypeDescriptor<T> |
|||
extends AbstractTypeDescriptor<T> implements DynamicParameterizedType { |
|||
|
|||
private Class<T> arrayObjectClass; |
|||
|
|||
private String sqlArrayType; |
|||
|
|||
public AbstractArrayTypeDescriptor(Class<T> arrayObjectClass) { |
|||
this(arrayObjectClass, (MutabilityPlan<T>) new MutableMutabilityPlan<Object>() { |
|||
@Override |
|||
protected T deepCopyNotNull(Object value) { |
|||
return ArrayUtil.deepCopy(value); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
protected AbstractArrayTypeDescriptor(Class<T> arrayObjectClass, MutabilityPlan<T> mutableMutabilityPlan) { |
|||
super(arrayObjectClass, mutableMutabilityPlan); |
|||
this.arrayObjectClass = arrayObjectClass; |
|||
} |
|||
|
|||
public Class<T> getArrayObjectClass() { |
|||
return arrayObjectClass; |
|||
} |
|||
|
|||
public void setArrayObjectClass(Class<T> arrayObjectClass) { |
|||
this.arrayObjectClass = arrayObjectClass; |
|||
} |
|||
|
|||
@Override |
|||
public void setParameterValues(Properties parameters) { |
|||
if (parameters.containsKey(PARAMETER_TYPE)) { |
|||
arrayObjectClass = ((ParameterType) parameters.get(PARAMETER_TYPE)).getReturnedClass(); |
|||
} |
|||
sqlArrayType = parameters.getProperty(SQL_ARRAY_TYPE); |
|||
} |
|||
|
|||
@Override |
|||
public boolean areEqual(T one, T another) { |
|||
if (one == another) { |
|||
return true; |
|||
} |
|||
if (one == null || another == null) { |
|||
return false; |
|||
} |
|||
return ArrayUtil.isEquals(one, another); |
|||
} |
|||
|
|||
@Override |
|||
public String toString(T value) { |
|||
return Arrays.deepToString(ArrayUtil.wrapArray(value)); |
|||
} |
|||
|
|||
@Override |
|||
public T fromString(String string) { |
|||
return ArrayUtil.fromString(string, arrayObjectClass); |
|||
} |
|||
|
|||
@Override |
|||
public String extractLoggableRepresentation(T value) { |
|||
return (value == null) ? "null" : toString(value); |
|||
} |
|||
|
|||
@SuppressWarnings({"unchecked"}) |
|||
@Override |
|||
public <X> X unwrap(T value, Class<X> type, WrapperOptions options) { |
|||
return (X) ArrayUtil.wrapArray(value); |
|||
} |
|||
|
|||
@Override |
|||
public <X> T wrap(X value, WrapperOptions options) { |
|||
if (value instanceof Array) { |
|||
Array array = (Array) value; |
|||
try { |
|||
return ArrayUtil.unwrapArray((Object[]) array.getArray(), arrayObjectClass); |
|||
} catch (SQLException e) { |
|||
throw new HibernateException( |
|||
new IllegalArgumentException(e) |
|||
); |
|||
} |
|||
} |
|||
return (T) value; |
|||
} |
|||
|
|||
protected String getSqlArrayType() { |
|||
return sqlArrayType; |
|||
} |
|||
} |
|||
@ -1,86 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
import org.hibernate.type.descriptor.ValueBinder; |
|||
import org.hibernate.type.descriptor.ValueExtractor; |
|||
import org.hibernate.type.descriptor.WrapperOptions; |
|||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; |
|||
import org.hibernate.type.descriptor.sql.BasicBinder; |
|||
import org.hibernate.type.descriptor.sql.BasicExtractor; |
|||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; |
|||
|
|||
import java.sql.CallableStatement; |
|||
import java.sql.PreparedStatement; |
|||
import java.sql.ResultSet; |
|||
import java.sql.SQLException; |
|||
import java.sql.Types; |
|||
|
|||
public class ArraySqlTypeDescriptor implements SqlTypeDescriptor { |
|||
|
|||
public static final ArraySqlTypeDescriptor INSTANCE = new ArraySqlTypeDescriptor(); |
|||
|
|||
@Override |
|||
public int getSqlType() { |
|||
return Types.ARRAY; |
|||
} |
|||
|
|||
@Override |
|||
public boolean canBeRemapped() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) { |
|||
return new BasicBinder<X>(javaTypeDescriptor, this) { |
|||
@Override |
|||
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException { |
|||
AbstractArrayTypeDescriptor<Object> abstractArrayTypeDescriptor = (AbstractArrayTypeDescriptor<Object>) javaTypeDescriptor; |
|||
st.setArray(index, st.getConnection().createArrayOf( |
|||
abstractArrayTypeDescriptor.getSqlArrayType(), |
|||
abstractArrayTypeDescriptor.unwrap(value, Object[].class, options) |
|||
)); |
|||
} |
|||
|
|||
@Override |
|||
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) |
|||
throws SQLException { |
|||
throw new UnsupportedOperationException("Binding by name is not supported!"); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
@Override |
|||
public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) { |
|||
return new BasicExtractor<X>(javaTypeDescriptor, this) { |
|||
@Override |
|||
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { |
|||
return javaTypeDescriptor.wrap(rs.getArray(name), options); |
|||
} |
|||
|
|||
@Override |
|||
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException { |
|||
return javaTypeDescriptor.wrap(statement.getArray(index), options); |
|||
} |
|||
|
|||
@Override |
|||
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException { |
|||
return javaTypeDescriptor.wrap(statement.getArray(name), options); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
} |
|||
@ -1,335 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
import java.lang.reflect.Array; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
|
|||
public class ArrayUtil { |
|||
|
|||
public static <T> T deepCopy(Object originalArray) { |
|||
Class arrayClass = originalArray.getClass(); |
|||
|
|||
if (boolean[].class.equals(arrayClass)) { |
|||
boolean[] array = (boolean[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (byte[].class.equals(arrayClass)) { |
|||
byte[] array = (byte[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (short[].class.equals(arrayClass)) { |
|||
short[] array = (short[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (int[].class.equals(arrayClass)) { |
|||
int[] array = (int[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (long[].class.equals(arrayClass)) { |
|||
long[] array = (long[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (float[].class.equals(arrayClass)) { |
|||
float[] array = (float[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (double[].class.equals(arrayClass)) { |
|||
double[] array = (double[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else if (char[].class.equals(arrayClass)) { |
|||
char[] array = (char[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} else { |
|||
Object[] array = (Object[]) originalArray; |
|||
return (T) Arrays.copyOf(array, array.length); |
|||
} |
|||
} |
|||
|
|||
public static Object[] wrapArray(Object originalArray) { |
|||
Class arrayClass = originalArray.getClass(); |
|||
|
|||
if (boolean[].class.equals(arrayClass)) { |
|||
boolean[] fromArray = (boolean[]) originalArray; |
|||
Boolean[] array = new Boolean[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (byte[].class.equals(arrayClass)) { |
|||
byte[] fromArray = (byte[]) originalArray; |
|||
Byte[] array = new Byte[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (short[].class.equals(arrayClass)) { |
|||
short[] fromArray = (short[]) originalArray; |
|||
Short[] array = new Short[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (int[].class.equals(arrayClass)) { |
|||
int[] fromArray = (int[]) originalArray; |
|||
Integer[] array = new Integer[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (long[].class.equals(arrayClass)) { |
|||
long[] fromArray = (long[]) originalArray; |
|||
Long[] array = new Long[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (float[].class.equals(arrayClass)) { |
|||
float[] fromArray = (float[]) originalArray; |
|||
Float[] array = new Float[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (double[].class.equals(arrayClass)) { |
|||
double[] fromArray = (double[]) originalArray; |
|||
Double[] array = new Double[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (char[].class.equals(arrayClass)) { |
|||
char[] fromArray = (char[]) originalArray; |
|||
Character[] array = new Character[fromArray.length]; |
|||
for (int i = 0; i < fromArray.length; i++) { |
|||
array[i] = fromArray[i]; |
|||
} |
|||
return array; |
|||
} else if (originalArray instanceof Collection) { |
|||
return ((Collection) originalArray).toArray(); |
|||
} else { |
|||
return (Object[]) originalArray; |
|||
} |
|||
} |
|||
|
|||
public static <T> T unwrapArray(Object[] originalArray, Class<T> arrayClass) { |
|||
|
|||
if (boolean[].class.equals(arrayClass)) { |
|||
boolean[] array = new boolean[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Boolean) originalArray[i] : Boolean.FALSE; |
|||
} |
|||
return (T) array; |
|||
} else if (byte[].class.equals(arrayClass)) { |
|||
byte[] array = new byte[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Byte) originalArray[i] : 0; |
|||
} |
|||
return (T) array; |
|||
} else if (short[].class.equals(arrayClass)) { |
|||
short[] array = new short[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Short) originalArray[i] : 0; |
|||
} |
|||
return (T) array; |
|||
} else if (int[].class.equals(arrayClass)) { |
|||
int[] array = new int[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Integer) originalArray[i] : 0; |
|||
} |
|||
return (T) array; |
|||
} else if (long[].class.equals(arrayClass)) { |
|||
long[] array = new long[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Long) originalArray[i] : 0L; |
|||
} |
|||
return (T) array; |
|||
} else if (float[].class.equals(arrayClass)) { |
|||
float[] array = new float[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? ((Number) originalArray[i]).floatValue() : 0f; |
|||
} |
|||
return (T) array; |
|||
} else if (double[].class.equals(arrayClass)) { |
|||
double[] array = new double[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Double) originalArray[i] : 0d; |
|||
} |
|||
return (T) array; |
|||
} else if (char[].class.equals(arrayClass)) { |
|||
char[] array = new char[originalArray.length]; |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = originalArray[i] != null ? (Character) originalArray[i] : 0; |
|||
} |
|||
return (T) array; |
|||
} else if (Enum[].class.isAssignableFrom(arrayClass)) { |
|||
T array = arrayClass.cast(Array.newInstance(arrayClass.getComponentType(), originalArray.length)); |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
Object objectValue = originalArray[i]; |
|||
if (objectValue != null) { |
|||
String stringValue = (objectValue instanceof String) ? (String) objectValue : String.valueOf(objectValue); |
|||
objectValue = Enum.valueOf((Class) arrayClass.getComponentType(), stringValue); |
|||
} |
|||
Array.set(array, i, objectValue); |
|||
} |
|||
return array; |
|||
} else if (java.time.LocalDate[].class.equals(arrayClass) && java.sql.Date[].class.equals(originalArray.getClass())) { |
|||
// special case because conversion is neither with ctor nor valueOf
|
|||
Object[] array = (Object[]) Array.newInstance(java.time.LocalDate.class, originalArray.length); |
|||
for (int i = 0; i < array.length; ++i) { |
|||
array[i] = originalArray[i] != null ? ((java.sql.Date) originalArray[i]).toLocalDate() : null; |
|||
} |
|||
return (T) array; |
|||
} else if (java.time.LocalDateTime[].class.equals(arrayClass) && java.sql.Timestamp[].class.equals(originalArray.getClass())) { |
|||
// special case because conversion is neither with ctor nor valueOf
|
|||
Object[] array = (Object[]) Array.newInstance(java.time.LocalDateTime.class, originalArray.length); |
|||
for (int i = 0; i < array.length; ++i) { |
|||
array[i] = originalArray[i] != null ? ((java.sql.Timestamp) originalArray[i]).toLocalDateTime() : null; |
|||
} |
|||
return (T) array; |
|||
} else if(arrayClass.getComponentType() != null && arrayClass.getComponentType().isArray()) { |
|||
int arrayLength = originalArray.length; |
|||
Object[] array = (Object[]) Array.newInstance(arrayClass.getComponentType(), arrayLength); |
|||
if (arrayLength > 0) { |
|||
for (int i = 0; i < originalArray.length; i++) { |
|||
array[i] = unwrapArray((Object[]) originalArray[i], arrayClass.getComponentType()); |
|||
} |
|||
} |
|||
return (T) array; |
|||
} else { |
|||
if (arrayClass.isInstance(originalArray)) { |
|||
return (T) originalArray; |
|||
} else { |
|||
return (T) Arrays.copyOf(originalArray, originalArray.length, (Class) arrayClass); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static <T> T fromString(String string, Class<T> arrayClass) { |
|||
String stringArray = string.replaceAll("[\\[\\]]", ""); |
|||
String[] tokens = stringArray.split(","); |
|||
|
|||
int length = tokens.length; |
|||
|
|||
if (boolean[].class.equals(arrayClass)) { |
|||
boolean[] array = new boolean[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Boolean.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (byte[].class.equals(arrayClass)) { |
|||
byte[] array = new byte[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Byte.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (short[].class.equals(arrayClass)) { |
|||
short[] array = new short[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Short.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (int[].class.equals(arrayClass)) { |
|||
int[] array = new int[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Integer.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (long[].class.equals(arrayClass)) { |
|||
long[] array = new long[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Long.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (float[].class.equals(arrayClass)) { |
|||
float[] array = new float[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Float.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (double[].class.equals(arrayClass)) { |
|||
double[] array = new double[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = Double.valueOf(tokens[i]); |
|||
} |
|||
return (T) array; |
|||
} else if (char[].class.equals(arrayClass)) { |
|||
char[] array = new char[length]; |
|||
for (int i = 0; i < tokens.length; i++) { |
|||
array[i] = tokens[i].length() > 0 ? tokens[i].charAt(0) : Character.MIN_VALUE; |
|||
} |
|||
return (T) array; |
|||
} else { |
|||
return (T) tokens; |
|||
} |
|||
} |
|||
|
|||
public static boolean isEquals(Object firstArray, Object secondArray) { |
|||
if (firstArray.getClass() != secondArray.getClass()) { |
|||
return false; |
|||
} |
|||
Class arrayClass = firstArray.getClass(); |
|||
|
|||
if (boolean[].class.equals(arrayClass)) { |
|||
return Arrays.equals((boolean[]) firstArray, (boolean[]) secondArray); |
|||
} else if (byte[].class.equals(arrayClass)) { |
|||
return Arrays.equals((byte[]) firstArray, (byte[]) secondArray); |
|||
} else if (short[].class.equals(arrayClass)) { |
|||
return Arrays.equals((short[]) firstArray, (short[]) secondArray); |
|||
} else if (int[].class.equals(arrayClass)) { |
|||
return Arrays.equals((int[]) firstArray, (int[]) secondArray); |
|||
} else if (long[].class.equals(arrayClass)) { |
|||
return Arrays.equals((long[]) firstArray, (long[]) secondArray); |
|||
} else if (float[].class.equals(arrayClass)) { |
|||
return Arrays.equals((float[]) firstArray, (float[]) secondArray); |
|||
} else if (double[].class.equals(arrayClass)) { |
|||
return Arrays.equals((double[]) firstArray, (double[]) secondArray); |
|||
} else if (char[].class.equals(arrayClass)) { |
|||
return Arrays.equals((char[]) firstArray, (char[]) secondArray); |
|||
} else { |
|||
return Arrays.equals((Object[]) firstArray, (Object[]) secondArray); |
|||
} |
|||
} |
|||
|
|||
public static <T> Class<T[]> toArrayClass(Class<T> arrayElementClass) { |
|||
|
|||
if (boolean.class.equals(arrayElementClass)) { |
|||
return (Class) boolean[].class; |
|||
} else if (byte.class.equals(arrayElementClass)) { |
|||
return (Class) byte[].class; |
|||
} else if (short.class.equals(arrayElementClass)) { |
|||
return (Class) short[].class; |
|||
} else if (int.class.equals(arrayElementClass)) { |
|||
return (Class) int[].class; |
|||
} else if (long.class.equals(arrayElementClass)) { |
|||
return (Class) long[].class; |
|||
} else if (float.class.equals(arrayElementClass)) { |
|||
return (Class) float[].class; |
|||
} else if (double[].class.equals(arrayElementClass)) { |
|||
return (Class) double[].class; |
|||
} else if (char[].class.equals(arrayElementClass)) { |
|||
return (Class) char[].class; |
|||
} else { |
|||
Object array = Array.newInstance(arrayElementClass, 0); |
|||
return (Class<T[]>) array.getClass(); |
|||
} |
|||
} |
|||
|
|||
public static <T> List<T> asList(T[] array) { |
|||
List<T> list = new ArrayList<T>(array.length); |
|||
for (int i = 0; i < array.length; i++) { |
|||
list.add(i, array[i]); |
|||
} |
|||
return list; |
|||
} |
|||
} |
|||
@ -1,64 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
import org.hibernate.usertype.DynamicParameterizedType; |
|||
|
|||
import java.lang.annotation.Annotation; |
|||
|
|||
public class ParameterizedParameterType implements DynamicParameterizedType.ParameterType { |
|||
|
|||
private final Class<?> clasz; |
|||
|
|||
public ParameterizedParameterType(Class<?> clasz) { |
|||
this.clasz = clasz; |
|||
} |
|||
|
|||
@Override |
|||
public Class getReturnedClass() { |
|||
return clasz; |
|||
} |
|||
|
|||
@Override |
|||
public Annotation[] getAnnotationsMethod() { |
|||
return new Annotation[0]; |
|||
} |
|||
|
|||
@Override |
|||
public String getCatalog() { |
|||
throw new UnsupportedOperationException(); |
|||
} |
|||
|
|||
@Override |
|||
public String getSchema() { |
|||
throw new UnsupportedOperationException(); |
|||
} |
|||
|
|||
@Override |
|||
public String getTable() { |
|||
throw new UnsupportedOperationException(); |
|||
} |
|||
|
|||
@Override |
|||
public boolean isPrimaryKey() { |
|||
throw new UnsupportedOperationException(); |
|||
} |
|||
|
|||
@Override |
|||
public String[] getColumns() { |
|||
throw new UnsupportedOperationException(); |
|||
} |
|||
} |
|||
@ -1,41 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
import org.hibernate.usertype.DynamicParameterizedType; |
|||
import java.util.Properties; |
|||
|
|||
public class StringArrayType extends AbstractArrayType<String[]> { |
|||
|
|||
public static final StringArrayType INSTANCE = new StringArrayType(); |
|||
|
|||
public StringArrayType() { |
|||
super( |
|||
new StringArrayTypeDescriptor() |
|||
); |
|||
} |
|||
|
|||
public StringArrayType(Class arrayClass) { |
|||
this(); |
|||
Properties parameters = new Properties(); |
|||
parameters.put(DynamicParameterizedType.PARAMETER_TYPE, new ParameterizedParameterType(arrayClass)); |
|||
setParameterValues(parameters); |
|||
} |
|||
|
|||
public String getName() { |
|||
return "string-array"; |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.util.mapping; |
|||
|
|||
public class StringArrayTypeDescriptor |
|||
extends AbstractArrayTypeDescriptor<String[]> { |
|||
|
|||
public StringArrayTypeDescriptor() { |
|||
super(String[].class); |
|||
} |
|||
|
|||
@Override |
|||
protected String getSqlArrayType() { |
|||
String sqlArrayType = super.getSqlArrayType(); |
|||
return sqlArrayType != null ? sqlArrayType : "text"; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,50 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* 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 org.thingsboard.server.dao.service; |
|||
|
|||
import org.junit.Assert; |
|||
import org.junit.Test; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.thingsboard.server.cache.TbTransactionalCache; |
|||
import org.thingsboard.server.common.data.EntitySubtype; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
@DaoSqlTest |
|||
public class TbCacheSerializationTest extends AbstractServiceTest { |
|||
|
|||
@Autowired |
|||
TbTransactionalCache<TenantId, PageData<EntitySubtype>> alarmTypesCache; |
|||
|
|||
@Test |
|||
public void AlarmTypesSerializationTest() { |
|||
var typesCount = 13; |
|||
TenantId tenantId = new TenantId(UUID.randomUUID()); |
|||
List<EntitySubtype> types = new ArrayList<>(typesCount); |
|||
for (int i = 0; i < typesCount; i++) { |
|||
types.add(new EntitySubtype(tenantId, EntityType.ALARM, "alarm_type_" + i)); |
|||
} |
|||
PageData<EntitySubtype> alarmTypesPage = new PageData<>(types, 1, typesCount, false); |
|||
alarmTypesCache.put(tenantId, alarmTypesPage); |
|||
PageData<EntitySubtype> foundAlarmTypes = alarmTypesCache.get(tenantId).get(); |
|||
Assert.assertEquals(alarmTypesPage, foundAlarmTypes); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue