| /*
|
| * Copyright 1999-2011 Alibaba Group.
|
| *
|
| * Licensed 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 com.alibaba.dubbo.common.serialize.support.dubbo; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import com.alibaba.dubbo.common.io.ClassDescriptorMapper; |
| import com.alibaba.dubbo.common.serialize.ObjectOutput; |
| import com.alibaba.dubbo.common.utils.ReflectUtils; |
| |
| /** |
| * Generic Object Output. |
| * |
| * @author qian.lei |
| */ |
| |
| public class GenericObjectOutput extends GenericDataOutput implements ObjectOutput |
| { |
| private ClassDescriptorMapper mMapper; |
| |
| private Map<Object, Integer> mRefs = new ConcurrentHashMap<Object, Integer>(); |
| |
| private final boolean isAllowNonSerializable; |
| |
| public GenericObjectOutput(OutputStream out) |
| { |
| this(out, Builder.DEFAULT_CLASS_DESCRIPTOR_MAPPER); |
| } |
| |
| public GenericObjectOutput(OutputStream out, ClassDescriptorMapper mapper) |
| { |
| super(out); |
| mMapper = mapper; |
| isAllowNonSerializable = false; |
| } |
| |
| public GenericObjectOutput(OutputStream out, int buffSize) |
| { |
| this(out, buffSize, Builder.DEFAULT_CLASS_DESCRIPTOR_MAPPER, false); |
| } |
| |
| public GenericObjectOutput(OutputStream out, int buffSize, ClassDescriptorMapper mapper) |
| { |
| this(out, buffSize, mapper, false); |
| } |
| |
| public GenericObjectOutput(OutputStream out, int buffSize, ClassDescriptorMapper mapper, boolean isAllowNonSerializable) |
| { |
| super(out, buffSize); |
| mMapper = mapper; |
| this.isAllowNonSerializable = isAllowNonSerializable; |
| } |
| |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| public void writeObject(Object obj) throws IOException |
| { |
| if( obj == null ) |
| { |
| write0(OBJECT_NULL); |
| return; |
| } |
| |
| Class<?> c = obj.getClass(); |
| if( c == Object.class ) |
| { |
| write0(OBJECT_DUMMY); |
| } |
| else |
| { |
| String desc = ReflectUtils.getDesc(c); |
| int index = mMapper.getDescriptorIndex(desc); |
| if( index < 0 ) |
| { |
| write0(OBJECT_DESC); |
| writeUTF(desc); |
| } |
| else |
| { |
| write0(OBJECT_DESC_ID); |
| writeUInt(index); |
| } |
| Builder b = Builder.register(c, isAllowNonSerializable); |
| b.writeTo(obj, this); |
| } |
| } |
| |
| public void addRef(Object obj) |
| { |
| mRefs.put(obj, mRefs.size()); |
| } |
| |
| public int getRef(Object obj) |
| { |
| Integer ref = mRefs.get(obj); |
| if( ref == null ) |
| return -1; |
| return ref.intValue(); |
| } |
| } |