blob: 3dc48a6e57625e182df393ffad1572b4117d955d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You 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.apache.geode.pdx.internal;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.tcp.ByteBufferInputStream.ByteSource;
import org.apache.geode.pdx.PdxFieldAlreadyExistsException;
import org.apache.geode.pdx.PdxUnreadFields;
/**
* @since GemFire 6.6
*/
public class PdxUnreadData implements PdxUnreadFields {
/**
* This is the original type of the blob that we deserialized and did not read some of its fields.
*/
private UnreadPdxType unreadType;
private byte[][] unreadData;
public PdxUnreadData() {
// initialize may be called later
}
public PdxUnreadData(UnreadPdxType unreadType, PdxReaderImpl reader) {
initialize(unreadType, reader);
}
public void initialize(UnreadPdxType unreadType, PdxReaderImpl reader) {
this.unreadType = unreadType;
int[] indexes = unreadType.getUnreadFieldIndexes();
this.unreadData = new byte[indexes.length][];
int i = 0;
for (int idx : indexes) {
ByteSource field = reader.getRaw(idx);
// Copy the unread data into a new byte array
this.unreadData[i] = new byte[field.capacity()];
field.position(0);
field.get(this.unreadData[i]);
i++;
}
}
public UnreadPdxType getUnreadType() {
return this.unreadType;
}
/**
* Returns the PdxType to use when serializing this unread data. Returns null if we don't know
* what this type is yet.
*
* @return the PdxType to use when serializing this unread data.
*/
public PdxType getSerializedType() {
return getUnreadType().getSerializedType();
}
public void setSerializedType(PdxType t) {
getUnreadType().setSerializedType(t);
}
public void sendTo(PdxWriterImpl writer) {
if (isEmpty())
return;
int[] indexes = this.unreadType.getUnreadFieldIndexes();
int i = 0;
while (i < this.unreadData.length) {
int idx = indexes[i];
byte[] data = this.unreadData[i];
PdxField ft = this.unreadType.getPdxFieldByIndex(idx);
try {
writer.writeRawField(ft, data);
} catch (PdxFieldAlreadyExistsException ex) {
// fix for bug 43133
throw new PdxFieldAlreadyExistsException(
"Check the toData and fromData for " + this.unreadType.getClassName()
+ " to see if the field \"" + ft.getFieldName() + "\" is spelled differently.");
}
i++;
}
}
/**
* If o has unread data then add that unread data to copy.
*/
public static void copy(Object o, Object copy) {
// This method is only called by CopyHelper which is public and does not require that a Cache
// exists.
// So we need to call getInstance instead of getExisting.
InternalCache cache = GemFireCacheImpl.getInstance();
if (cache == null)
return;
TypeRegistry tr = cache.getPdxRegistry();
PdxUnreadData ud = tr.getUnreadData(o);
if (ud != null && !ud.isEmpty()) {
tr.putUnreadData(copy, ud);
}
}
public boolean isEmpty() {
return this.unreadData == null;
}
}