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.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.usertype.UserType;
|
||||
import org.libreccm.hibernate.AbstractCcmJsonUserType;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
|
@ -42,120 +43,131 @@ import javax.json.JsonReader;
|
|||
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>
|
||||
*/
|
||||
public class LocalizedStringType implements UserType {
|
||||
public class LocalizedStringType extends AbstractCcmJsonUserType {
|
||||
|
||||
@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)) {
|
||||
protected Object nullSafeGet(final JsonReader jsonReader) {
|
||||
return LocalizedString.fromJson(jsonReader.readObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
final JsonObject jsonObject = ((LocalizedString) value).toJson();
|
||||
try (StringWriter strWriter = new StringWriter();
|
||||
JsonWriter jsonWriter = Json.createWriter(strWriter)) {
|
||||
jsonWriter.writeObject(jsonObject);
|
||||
statement.setObject(index, strWriter.toString(), Types.OTHER);
|
||||
} catch (IOException ex) {
|
||||
throw new HibernateException(ex);
|
||||
}
|
||||
}
|
||||
protected void nullSafeSet(
|
||||
final Object value, final JsonWriter jsonWriter
|
||||
) {
|
||||
jsonWriter.writeObject(((LocalizedString) value).toJson());
|
||||
}
|
||||
//implements UserType {
|
||||
|
||||
@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 (final ByteArrayInputStream bais = new ByteArrayInputStream(
|
||||
serialized
|
||||
);
|
||||
final 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);
|
||||
}
|
||||
// @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 LocalizedString.fromJson(jsonReader.readObject());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @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 {
|
||||
// final JsonObject jsonObject = ((LocalizedString) value).toJson();
|
||||
// try (StringWriter strWriter = new StringWriter();
|
||||
// JsonWriter jsonWriter = Json.createWriter(strWriter)) {
|
||||
// jsonWriter.writeObject(jsonObject);
|
||||
// statement.setObject(index, strWriter.toString(), Types.OTHER);
|
||||
// } catch (IOException ex) {
|
||||
// throw new HibernateException(ex);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @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);
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue