blob: 624df7f2d375f619f0909c90b9e0a0b481ff892e [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 java.util.Date;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.pdx.PdxInstance;
import org.apache.geode.pdx.PdxInstanceFactory;
/**
* PdxInstances created with this factory can never be deserialized but you can access their fields
* just like any other pdx.
* <p>
* The current implementation of this interface is meant for internal use only. The way it defines a
* PdxType is expensive since it can never figure out it is already defined without doing an
* expensive check in the type registry. We should optimize this before making this a public
* feature.
*/
public class PdxInstanceFactoryImpl implements PdxInstanceFactory {
private final PdxWriterImpl writer;
private final PdxType pdxType;
private boolean created = false;
private PdxInstanceFactoryImpl(String name, boolean expectDomainClass, TypeRegistry pdxRegistry) {
if (name == null) {
throw new IllegalArgumentException(
"Class name can not be null when creating a PdxInstanceFactory");
}
if (name.isEmpty()) {
expectDomainClass = false;
}
PdxOutputStream pdxOutputStream = new PdxOutputStream();
this.pdxType = new PdxType(name, expectDomainClass);
this.writer = new PdxWriterImpl(pdxType, pdxRegistry, pdxOutputStream);
}
public static PdxInstanceFactory newCreator(String name, boolean expectDomainClass,
InternalCache cache) {
return new PdxInstanceFactoryImpl(name, expectDomainClass, cache.getPdxRegistry());
}
@Override
public PdxInstance create() {
if (this.created) {
throw new IllegalStateException("The create method can only be called once.");
}
this.created = true;
this.writer.completeByteStreamGeneration();
return this.writer.makePdxInstance();
}
@Override
public PdxInstanceFactory writeChar(String fieldName, char value) {
this.writer.writeChar(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeBoolean(String fieldName, boolean value) {
this.writer.writeBoolean(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeByte(String fieldName, byte value) {
this.writer.writeByte(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeShort(String fieldName, short value) {
this.writer.writeShort(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeInt(String fieldName, int value) {
this.writer.writeInt(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeLong(String fieldName, long value) {
this.writer.writeLong(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeFloat(String fieldName, float value) {
this.writer.writeFloat(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeDouble(String fieldName, double value) {
this.writer.writeDouble(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeDate(String fieldName, Date value) {
this.writer.writeDate(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeString(String fieldName, String value) {
this.writer.writeString(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeObject(String fieldName, Object value) {
return writeObject(fieldName, value, false);
}
@Override
public PdxInstanceFactory writeBooleanArray(String fieldName, boolean[] value) {
this.writer.writeBooleanArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeCharArray(String fieldName, char[] value) {
this.writer.writeCharArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeByteArray(String fieldName, byte[] value) {
this.writer.writeByteArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeShortArray(String fieldName, short[] value) {
this.writer.writeShortArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeIntArray(String fieldName, int[] value) {
this.writer.writeIntArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeLongArray(String fieldName, long[] value) {
this.writer.writeLongArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeFloatArray(String fieldName, float[] value) {
this.writer.writeFloatArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeDoubleArray(String fieldName, double[] value) {
this.writer.writeDoubleArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeStringArray(String fieldName, String[] value) {
this.writer.writeStringArray(fieldName, value);
return this;
}
@Override
public PdxInstanceFactory writeObjectArray(String fieldName, Object[] value) {
return writeObjectArray(fieldName, value, false);
}
@Override
public PdxInstanceFactory writeArrayOfByteArrays(String fieldName, byte[][] value) {
this.writer.writeArrayOfByteArrays(fieldName, value);
return this;
}
@Override
public <CT, VT extends CT> PdxInstanceFactory writeField(String fieldName, VT fieldValue,
Class<CT> fieldType) {
return writeField(fieldName, fieldValue, fieldType, false);
}
@Override
public PdxInstanceFactory markIdentityField(String fieldName) {
this.writer.markIdentityField(fieldName);
return this;
}
@Override
public PdxInstanceFactory writeObject(String fieldName, Object value, boolean checkPortability) {
if (InternalDataSerializer.is662SerializationEnabled()) {
boolean alreadyInProgress = InternalDataSerializer.isPdxSerializationInProgress();
if (!alreadyInProgress) {
InternalDataSerializer.setPdxSerializationInProgress(true);
try {
this.writer.writeObject(fieldName, value, checkPortability);
} finally {
InternalDataSerializer.setPdxSerializationInProgress(false);
}
} else {
this.writer.writeObject(fieldName, value, checkPortability);
}
} else {
this.writer.writeObject(fieldName, value, checkPortability);
}
return this;
}
@Override
public PdxInstanceFactory writeObjectArray(String fieldName, Object[] value,
boolean checkPortability) {
if (InternalDataSerializer.is662SerializationEnabled()) {
boolean alreadyInProgress = InternalDataSerializer.isPdxSerializationInProgress();
if (!alreadyInProgress) {
InternalDataSerializer.setPdxSerializationInProgress(true);
try {
this.writer.writeObjectArray(fieldName, value, checkPortability);
} finally {
InternalDataSerializer.setPdxSerializationInProgress(false);
}
} else {
this.writer.writeObjectArray(fieldName, value, checkPortability);
}
} else {
this.writer.writeObjectArray(fieldName, value, checkPortability);
}
return this;
}
@Override
public <CT, VT extends CT> PdxInstanceFactory writeField(String fieldName, VT fieldValue,
Class<CT> fieldType, boolean checkPortability) {
if (InternalDataSerializer.is662SerializationEnabled()) {
boolean alreadyInProgress = InternalDataSerializer.isPdxSerializationInProgress();
if (!alreadyInProgress) {
InternalDataSerializer.setPdxSerializationInProgress(true);
try {
this.writer.writeField(fieldName, fieldValue, fieldType, checkPortability);
} finally {
InternalDataSerializer.setPdxSerializationInProgress(false);
}
} else {
this.writer.writeField(fieldName, fieldValue, fieldType, checkPortability);
}
} else {
this.writer.writeField(fieldName, fieldValue, fieldType, checkPortability);
}
return this;
}
public static PdxInstance createPdxEnum(String className, String enumName, int enumOrdinal,
InternalCache internalCache) {
if (className == null) {
throw new IllegalArgumentException("className must not be null");
}
if (enumName == null) {
throw new IllegalArgumentException("enumName must not be null");
}
TypeRegistry tr = internalCache.getPdxRegistry();
EnumInfo ei = new EnumInfo(className, enumName, enumOrdinal);
return ei.getPdxInstance(tr.defineEnum(ei));
}
@Override
public PdxInstanceFactory neverDeserialize() {
this.pdxType.setNoDomainClass(true);
return this;
}
}