use of org.apache.geode.DataSerializer in project geode by apache.
the class InternalDataSerializer method writeUserObject.
/**
* Data serializes an instance of a "user class" (that is, a class that can be handled by a
* registered {@code DataSerializer}) to the given {@code DataOutput}.
*
* @return {@code true} if {@code o} was written to {@code out}.
*/
private static boolean writeUserObject(Object o, DataOutput out, boolean ensurePdxCompatibility) throws IOException {
final Class<?> c = o.getClass();
final DataSerializer serializer = InternalDataSerializer.getSerializer(c);
if (serializer != null) {
int id = serializer.getId();
if (id != 0) {
checkPdxCompatible(o, ensurePdxCompatibility);
// id will be 0 if it is a WellKnowDS
if (id <= Byte.MAX_VALUE && id >= Byte.MIN_VALUE) {
out.writeByte(USER_CLASS);
out.writeByte((byte) id);
} else if (id <= Short.MAX_VALUE && id >= Short.MIN_VALUE) {
out.writeByte(USER_CLASS_2);
out.writeShort(id);
} else {
out.writeByte(USER_CLASS_4);
out.writeInt(id);
}
} else {
if (ensurePdxCompatibility) {
if (!(serializer instanceof WellKnownPdxDS)) {
checkPdxCompatible(o, ensurePdxCompatibility);
}
}
}
boolean toDataResult;
try {
toDataResult = serializer.toData(o, out);
} catch (IOException io) {
if (serializer instanceof WellKnownDS) {
// see bug 44659
throw io;
} else {
// with the plugin code.
throw new ToDataException("toData failed on DataSerializer with id=" + id + " for class " + c, io);
}
} catch (CancelException | ToDataException | GemFireRethrowable ex) {
// Serializing a PDX can result in a cache closed exception. Just rethrow
throw ex;
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// now, so don't let this thread continue.
throw err;
} catch (Throwable t) {
// Whenever you catch Error or Throwable, you must also
// catch VirtualMachineError (see above). However, there is
// _still_ a possibility that you are dealing with a cascading
// error condition, so you also need to check to see if the JVM
// is still usable:
SystemFailure.checkFailure();
throw new ToDataException("toData failed on DataSerializer with id=" + id + " for class " + c, t);
}
if (toDataResult) {
return true;
} else {
throw new ToDataException(LocalizedStrings.DataSerializer_SERIALIZER_0_A_1_SAID_THAT_IT_COULD_SERIALIZE_AN_INSTANCE_OF_2_BUT_ITS_TODATA_METHOD_RETURNED_FALSE.toLocalizedString(serializer.getId(), serializer.getClass().getName(), o.getClass().getName()));
}
// Do byte[][] and Object[] here to fix bug 44060
} else if (o instanceof byte[][]) {
byte[][] byteArrays = (byte[][]) o;
out.writeByte(ARRAY_OF_BYTE_ARRAYS);
writeArrayOfByteArrays(byteArrays, out);
return true;
} else if (o instanceof Object[]) {
Object[] array = (Object[]) o;
out.writeByte(OBJECT_ARRAY);
writeObjectArray(array, out, ensurePdxCompatibility);
return true;
} else if (is662SerializationEnabled() && (o.getClass().isEnum() || /* for bug 52271 */
(o.getClass().getSuperclass() != null && o.getClass().getSuperclass().isEnum()))) {
if (isPdxSerializationInProgress()) {
writePdxEnum((Enum<?>) o, out);
} else {
checkPdxCompatible(o, ensurePdxCompatibility);
writeGemFireEnum((Enum<?>) o, out);
}
return true;
} else {
PdxSerializer pdxSerializer = TypeRegistry.getPdxSerializer();
return pdxSerializer != null && writePdx(out, null, o, pdxSerializer);
}
}
use of org.apache.geode.DataSerializer in project geode by apache.
the class InternalDataSerializer method _register.
public static DataSerializer _register(DataSerializer s, boolean distribute) {
final int id = s.getId();
DataSerializer dsForMarkers = s;
if (id == 0) {
throw new IllegalArgumentException(LocalizedStrings.InternalDataSerializer_CANNOT_CREATE_A_DATASERIALIZER_WITH_ID_0.toLocalizedString());
}
final Class[] classes = s.getSupportedClasses();
if (classes == null || classes.length == 0) {
final StringId msg = LocalizedStrings.InternalDataSerializer_THE_DATASERIALIZER_0_HAS_NO_SUPPORTED_CLASSES_ITS_GETSUPPORTEDCLASSES_METHOD_MUST_RETURN_AT_LEAST_ONE_CLASS;
throw new IllegalArgumentException(msg.toLocalizedString(s.getClass().getName()));
}
for (Class aClass : classes) {
if (aClass == null) {
final StringId msg = LocalizedStrings.InternalDataSerializer_THE_DATASERIALIZER_GETSUPPORTEDCLASSES_METHOD_FOR_0_RETURNED_AN_ARRAY_THAT_CONTAINED_A_NULL_ELEMENT;
throw new IllegalArgumentException(msg.toLocalizedString(s.getClass().getName()));
} else if (aClass.isArray()) {
final StringId msg = LocalizedStrings.InternalDataSerializer_THE_DATASERIALIZER_GETSUPPORTEDCLASSES_METHOD_FOR_0_RETURNED_AN_ARRAY_THAT_CONTAINED_AN_ARRAY_CLASS_WHICH_IS_NOT_ALLOWED_SINCE_ARRAYS_HAVE_BUILTIN_SUPPORT;
throw new IllegalArgumentException(msg.toLocalizedString(s.getClass().getName()));
}
}
final Integer idx = id;
boolean retry;
Marker oldMarker = null;
final Marker m = new InitMarker();
do {
retry = false;
Object oldSerializer = idsToSerializers.putIfAbsent(idx, m);
if (oldSerializer != null) {
if (oldSerializer instanceof Marker) {
retry = !idsToSerializers.replace(idx, oldSerializer, m);
if (!retry) {
oldMarker = (Marker) oldSerializer;
}
} else if (oldSerializer.getClass().equals(s.getClass())) {
// We've already got one of these registered
if (distribute) {
sendRegistrationMessage(s);
}
return (DataSerializer) oldSerializer;
} else {
DataSerializer other = (DataSerializer) oldSerializer;
throw new IllegalStateException(LocalizedStrings.InternalDataSerializer_A_DATASERIALIZER_OF_CLASS_0_IS_ALREADY_REGISTERED_WITH_ID_1_SO_THE_DATASERIALIZER_OF_CLASS_2_COULD_NOT_BE_REGISTERED.toLocalizedString(new Object[] { other.getClass().getName(), other.getId() }));
}
}
} while (retry);
try {
for (int i = 0; i < classes.length; i++) {
DataSerializer oldS = classesToSerializers.putIfAbsent(classes[i].getName(), s);
if (oldS != null) {
if (!s.equals(oldS)) {
// cleanup the ones we have already added
for (int j = 0; j < i; j++) {
classesToSerializers.remove(classes[j].getName(), s);
}
dsForMarkers = null;
String oldMsg;
if (oldS.getId() == 0) {
oldMsg = "DataSerializer has built-in support for class ";
} else {
oldMsg = "A DataSerializer of class " + oldS.getClass().getName() + " is already registered to support class ";
}
String msg = oldMsg + classes[i].getName() + " so the DataSerializer of class " + s.getClass().getName() + " could not be registered.";
if (oldS.getId() == 0) {
throw new IllegalArgumentException(msg);
} else {
throw new IllegalStateException(msg);
}
}
}
}
} finally {
if (dsForMarkers == null) {
idsToSerializers.remove(idx, m);
} else {
idsToSerializers.replace(idx, m, dsForMarkers);
}
if (oldMarker != null) {
oldMarker.setSerializer(dsForMarkers);
}
m.setSerializer(dsForMarkers);
}
// if dataserializer is getting registered for first time
// its EventID will be null, so generate a new event id
// the the distributed system is connected
InternalCache cache = GemFireCacheImpl.getInstance();
if (cache != null && s.getEventId() == null) {
s.setEventId(new EventID(cache.getDistributedSystem()));
}
if (distribute) {
// send a message to other peers telling them about a newly-registered
// dataserializer, it also send event id of the originator along with the
// dataserializer
sendRegistrationMessage(s);
// send it to cache servers if it is a client
sendRegistrationMessageToServers(s);
}
// send it to all cache clients irrelevant of distribute
// bridge servers send it all the clients irrelevant of
// originator VM
sendRegistrationMessageToClients(s);
fireNewDataSerializer(s);
return s;
}
use of org.apache.geode.DataSerializer in project geode by apache.
the class InternalDataSerializer method getSerializersForDistribution.
/**
* Returns all the data serializers in this vm. This method, unlike {@link #getSerializers()},
* does not force loading of the data serializers which were not loaded in the vm earlier.
*
* @return Array of {@link SerializerAttributesHolder}
*/
public static SerializerAttributesHolder[] getSerializersForDistribution() {
final int size = idsToSerializers.size() + dsClassesToHolders.size();
Collection<SerializerAttributesHolder> coll = new ArrayList<>(size);
for (Object v : idsToSerializers.values()) {
if (v instanceof InitMarker) {
v = ((Marker) v).getSerializer();
}
if (v instanceof DataSerializer) {
DataSerializer s = (DataSerializer) v;
coll.add(new SerializerAttributesHolder(s.getClass().getName(), (EventID) s.getEventId(), (ClientProxyMembershipID) s.getContext(), s.getId()));
}
}
for (final Entry<String, SerializerAttributesHolder> stringSerializerAttributesHolderEntry : dsClassesToHolders.entrySet()) {
SerializerAttributesHolder v = stringSerializerAttributesHolderEntry.getValue();
coll.add(v);
}
return coll.toArray(new SerializerAttributesHolder[coll.size()]);
}
use of org.apache.geode.DataSerializer in project geode by apache.
the class CacheClientNotifier method writeMessage.
private void writeMessage(DataOutputStream dos, byte type, String p_msg, Version clientVersion, byte epType, int qSize) throws IOException {
String msg = p_msg;
// write the message type
dos.writeByte(type);
// dummy epType
dos.writeByte(epType);
// dummy qSize
dos.writeInt(qSize);
if (msg == null) {
msg = "";
}
dos.writeUTF(msg);
if (clientVersion != null && clientVersion.compareTo(Version.GFE_61) >= 0) {
// get all the instantiators.
Instantiator[] instantiators = InternalInstantiator.getInstantiators();
HashMap instantiatorMap = new HashMap();
if (instantiators != null && instantiators.length > 0) {
for (Instantiator instantiator : instantiators) {
ArrayList instantiatorAttributes = new ArrayList();
instantiatorAttributes.add(instantiator.getClass().toString().substring(6));
instantiatorAttributes.add(instantiator.getInstantiatedClass().toString().substring(6));
instantiatorMap.put(instantiator.getId(), instantiatorAttributes);
}
}
DataSerializer.writeHashMap(instantiatorMap, dos);
// get all the dataserializers.
DataSerializer[] dataSerializers = InternalDataSerializer.getSerializers();
HashMap<Integer, ArrayList<String>> dsToSupportedClasses = new HashMap<Integer, ArrayList<String>>();
HashMap<Integer, String> dataSerializersMap = new HashMap<Integer, String>();
if (dataSerializers != null && dataSerializers.length > 0) {
for (DataSerializer dataSerializer : dataSerializers) {
dataSerializersMap.put(dataSerializer.getId(), dataSerializer.getClass().toString().substring(6));
if (clientVersion.compareTo(Version.GFE_6516) >= 0) {
ArrayList<String> supportedClassNames = new ArrayList<String>();
for (Class clazz : dataSerializer.getSupportedClasses()) {
supportedClassNames.add(clazz.getName());
}
dsToSupportedClasses.put(dataSerializer.getId(), supportedClassNames);
}
}
}
DataSerializer.writeHashMap(dataSerializersMap, dos);
if (clientVersion.compareTo(Version.GFE_6516) >= 0) {
DataSerializer.writeHashMap(dsToSupportedClasses, dos);
}
}
dos.flush();
}
use of org.apache.geode.DataSerializer in project geode by apache.
the class DataSerializableJUnitTest method testSupportedClasses.
/**
* Tests that only one serializer is invoked when a serializer specifies its supported classes.
* Alos tests UDDS1.
*/
@Test
public void testSupportedClasses() throws Exception {
DataSerializer ds1 = DataSerializer.register(Class_testSupportedClasses1.class);
int id = ds1.getId();
DataSerializer ds2 = DataSerializer.register(Class_testSupportedClasses2.class);
int id2 = ds2.getId();
try {
Object o = new NonDataSerializable(new Random());
DataSerializer.writeObject(o, getDataOutput());
assertTrue(Class_testSupportedClasses2.wasInvoked);
assertTrue(Class_testSupportedClasses2.toDataInvoked);
assertFalse(Class_testSupportedClasses2.fromDataInvoked);
Object o2 = DataSerializer.readObject(getDataInput());
assertTrue(Class_testSupportedClasses2.fromDataInvoked);
assertEquals(o, o2);
} finally {
InternalDataSerializer.unregister(id);
InternalDataSerializer.unregister(id2);
}
}
Aggregations