Reducing boilerplate code for JSON mapping UserTypes
parent
e5d0e5f329
commit
1f970809b3
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 LibreCCM Foundation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.libreccm.hibernate;
|
||||||
|
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
import org.libreccm.l10n.LocalizedString;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.json.Json;
|
||||||
|
import javax.json.JsonReader;
|
||||||
|
import javax.json.JsonWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractCcmJsonUserType implements UserType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] sqlTypes() {
|
||||||
|
return new int[]{Types.JAVA_OBJECT};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<LocalizedString> returnedClass() {
|
||||||
|
return LocalizedString.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj1, final Object obj2)
|
||||||
|
throws HibernateException {
|
||||||
|
return Objects.equals(obj1, obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(final Object obj) throws HibernateException {
|
||||||
|
return Objects.hashCode(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object nullSafeGet(
|
||||||
|
final ResultSet resultSet,
|
||||||
|
final String[] names,
|
||||||
|
final SharedSessionContractImplementor session,
|
||||||
|
final Object owner
|
||||||
|
) throws HibernateException, SQLException {
|
||||||
|
final String cellContent = resultSet.getString(names[0]);
|
||||||
|
if (cellContent == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
try (StringReader strReader = new StringReader(cellContent);
|
||||||
|
JsonReader jsonReader = Json.createReader(strReader)) {
|
||||||
|
return nullSafeGet(jsonReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Object nullSafeGet(final JsonReader jsonReader);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nullSafeSet(
|
||||||
|
final PreparedStatement statement,
|
||||||
|
final Object value,
|
||||||
|
final int index,
|
||||||
|
final SharedSessionContractImplementor session
|
||||||
|
) throws HibernateException, SQLException {
|
||||||
|
if (value == null) {
|
||||||
|
statement.setObject(index, null, Types.OTHER);
|
||||||
|
} else {
|
||||||
|
try (StringWriter strWriter = new StringWriter();
|
||||||
|
JsonWriter jsonWriter = Json.createWriter(strWriter)) {
|
||||||
|
nullSafeSet(value, jsonWriter);
|
||||||
|
statement.setObject(index, strWriter.toString(), Types.OTHER);
|
||||||
|
}catch (IOException ex) {
|
||||||
|
throw new HibernateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void nullSafeSet(
|
||||||
|
final Object value, final JsonWriter jsonWriter
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object deepCopy(final Object value) throws HibernateException {
|
||||||
|
final byte[] serialized;
|
||||||
|
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
||||||
|
oos.writeObject(value);
|
||||||
|
oos.flush();
|
||||||
|
serialized = bos.toByteArray();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new HibernateException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object obj;
|
||||||
|
try (ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(bais)) {
|
||||||
|
obj = ois.readObject();
|
||||||
|
} catch (IOException | ClassNotFoundException ex) {
|
||||||
|
throw new HibernateException(ex);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable disassemble(final Object value)
|
||||||
|
throws HibernateException {
|
||||||
|
return (Serializable) deepCopy(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object assemble(final Serializable cached, final Object owner) throws
|
||||||
|
HibernateException {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object replace(
|
||||||
|
final Object original,
|
||||||
|
final Object target,
|
||||||
|
final Object owner
|
||||||
|
) throws HibernateException {
|
||||||
|
return deepCopy(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ package org.libreccm.l10n;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.usertype.UserType;
|
import org.hibernate.usertype.UserType;
|
||||||
|
import org.libreccm.hibernate.AbstractCcmJsonUserType;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
@ -42,120 +43,131 @@ import javax.json.JsonReader;
|
||||||
import javax.json.JsonWriter;
|
import javax.json.JsonWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Hibernate User type mapping instances of {@link LocalizedString} to a JSON.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public class LocalizedStringType implements UserType {
|
public class LocalizedStringType extends AbstractCcmJsonUserType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] sqlTypes() {
|
protected Object nullSafeGet(final JsonReader jsonReader) {
|
||||||
return new int[]{Types.JAVA_OBJECT};
|
return LocalizedString.fromJson(jsonReader.readObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<LocalizedString> returnedClass() {
|
protected void nullSafeSet(
|
||||||
return LocalizedString.class;
|
final Object value, final JsonWriter jsonWriter
|
||||||
|
) {
|
||||||
|
jsonWriter.writeObject(((LocalizedString) value).toJson());
|
||||||
}
|
}
|
||||||
|
//implements UserType {
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public boolean equals(final Object obj1, final Object obj2)
|
// public int[] sqlTypes() {
|
||||||
throws HibernateException {
|
// return new int[]{Types.JAVA_OBJECT};
|
||||||
return Objects.equals(obj1, obj2);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public Class<LocalizedString> returnedClass() {
|
||||||
public int hashCode(final Object obj) throws HibernateException {
|
// return LocalizedString.class;
|
||||||
return Objects.hashCode(obj);
|
// }
|
||||||
}
|
//
|
||||||
|
// @Override
|
||||||
@Override
|
// public boolean equals(final Object obj1, final Object obj2)
|
||||||
public Object nullSafeGet(
|
// throws HibernateException {
|
||||||
final ResultSet resultSet,
|
// return Objects.equals(obj1, obj2);
|
||||||
final String[] names,
|
// }
|
||||||
final SharedSessionContractImplementor session,
|
//
|
||||||
final Object owner
|
// @Override
|
||||||
) throws HibernateException, SQLException {
|
// public int hashCode(final Object obj) throws HibernateException {
|
||||||
final String cellContent = resultSet.getString(names[0]);
|
// return Objects.hashCode(obj);
|
||||||
if (cellContent == null) {
|
// }
|
||||||
return null;
|
//
|
||||||
} else {
|
// @Override
|
||||||
try (StringReader strReader = new StringReader(cellContent);
|
// public Object nullSafeGet(
|
||||||
JsonReader jsonReader = Json.createReader(strReader)) {
|
// final ResultSet resultSet,
|
||||||
return LocalizedString.fromJson(jsonReader.readObject());
|
// final String[] names,
|
||||||
}
|
// final SharedSessionContractImplementor session,
|
||||||
}
|
// final Object owner
|
||||||
}
|
// ) throws HibernateException, SQLException {
|
||||||
|
// final String cellContent = resultSet.getString(names[0]);
|
||||||
@Override
|
// if (cellContent == null) {
|
||||||
public void nullSafeSet(
|
// return null;
|
||||||
final PreparedStatement statement,
|
// } else {
|
||||||
final Object value,
|
// try (StringReader strReader = new StringReader(cellContent);
|
||||||
final int index,
|
// JsonReader jsonReader = Json.createReader(strReader)) {
|
||||||
final SharedSessionContractImplementor session
|
// return LocalizedString.fromJson(jsonReader.readObject());
|
||||||
) throws HibernateException, SQLException {
|
// }
|
||||||
if (value == null) {
|
// }
|
||||||
statement.setObject(index, null, Types.OTHER);
|
// }
|
||||||
} else {
|
//
|
||||||
final JsonObject jsonObject = ((LocalizedString) value).toJson();
|
// @Override
|
||||||
try (StringWriter strWriter = new StringWriter();
|
// public void nullSafeSet(
|
||||||
JsonWriter jsonWriter = Json.createWriter(strWriter)) {
|
// final PreparedStatement statement,
|
||||||
jsonWriter.writeObject(jsonObject);
|
// final Object value,
|
||||||
statement.setObject(index, strWriter.toString(), Types.OTHER);
|
// final int index,
|
||||||
} catch (IOException ex) {
|
// final SharedSessionContractImplementor session
|
||||||
throw new HibernateException(ex);
|
// ) throws HibernateException, SQLException {
|
||||||
}
|
// if (value == null) {
|
||||||
}
|
// statement.setObject(index, null, Types.OTHER);
|
||||||
}
|
// } else {
|
||||||
|
// final JsonObject jsonObject = ((LocalizedString) value).toJson();
|
||||||
@Override
|
// try (StringWriter strWriter = new StringWriter();
|
||||||
public Object deepCopy(final Object value) throws HibernateException {
|
// JsonWriter jsonWriter = Json.createWriter(strWriter)) {
|
||||||
final byte[] serialized;
|
// jsonWriter.writeObject(jsonObject);
|
||||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
// statement.setObject(index, strWriter.toString(), Types.OTHER);
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
// } catch (IOException ex) {
|
||||||
oos.writeObject(value);
|
// throw new HibernateException(ex);
|
||||||
oos.flush();
|
// }
|
||||||
serialized = bos.toByteArray();
|
// }
|
||||||
} catch (IOException ex) {
|
// }
|
||||||
throw new HibernateException(ex);
|
//
|
||||||
}
|
// @Override
|
||||||
|
// public Object deepCopy(final Object value) throws HibernateException {
|
||||||
final Object obj;
|
// final byte[] serialized;
|
||||||
try (final ByteArrayInputStream bais = new ByteArrayInputStream(
|
// try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
serialized
|
// ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
||||||
);
|
// oos.writeObject(value);
|
||||||
final ObjectInputStream ois = new ObjectInputStream(bais);) {
|
// oos.flush();
|
||||||
obj = ois.readObject();
|
// serialized = bos.toByteArray();
|
||||||
} catch (IOException | ClassNotFoundException ex) {
|
// } catch (IOException ex) {
|
||||||
throw new HibernateException(ex);
|
// throw new HibernateException(ex);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return obj;
|
// final Object obj;
|
||||||
}
|
// try (ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
|
||||||
|
// ObjectInputStream ois = new ObjectInputStream(bais)) {
|
||||||
@Override
|
// obj = ois.readObject();
|
||||||
public boolean isMutable() {
|
// } catch (IOException | ClassNotFoundException ex) {
|
||||||
return true;
|
// throw new HibernateException(ex);
|
||||||
}
|
// }
|
||||||
|
// return obj;
|
||||||
@Override
|
// }
|
||||||
public Serializable disassemble(final Object value)
|
//
|
||||||
throws HibernateException {
|
// @Override
|
||||||
return (Serializable) deepCopy(value);
|
// public boolean isMutable() {
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
@Override
|
//
|
||||||
public Object assemble(final Serializable cached, final Object owner) throws
|
// @Override
|
||||||
HibernateException {
|
// public Serializable disassemble(final Object value)
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
// throws HibernateException {
|
||||||
}
|
// return (Serializable) deepCopy(value);
|
||||||
|
// }
|
||||||
@Override
|
//
|
||||||
public Object replace(
|
// @Override
|
||||||
final Object original,
|
// public Object assemble(final Serializable cached, final Object owner) throws
|
||||||
final Object target,
|
// HibernateException {
|
||||||
final Object owner
|
// throw new UnsupportedOperationException("Not supported yet.");
|
||||||
) throws HibernateException {
|
// }
|
||||||
return deepCopy(original);
|
//
|
||||||
}
|
// @Override
|
||||||
|
// public Object replace(
|
||||||
|
// final Object original,
|
||||||
|
// final Object target,
|
||||||
|
// final Object owner
|
||||||
|
// ) throws HibernateException {
|
||||||
|
// return deepCopy(original);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue