Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.red5.io.amf.Output Maven / Gradle / Ivy
package org.red5.io.amf;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;
import org.apache.commons.beanutils.BeanMap;
import org.apache.mina.core.buffer.IoBuffer;
import org.red5.annotations.Anonymous;
import org.red5.io.amf3.ByteArray;
import org.red5.io.object.BaseOutput;
import org.red5.io.object.RecordSet;
import org.red5.io.object.Serializer;
import org.red5.io.utils.XMLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
public class Output extends BaseOutput implements org .red5 .io .object .Output {
protected static Logger log = LoggerFactory.getLogger(Output.class);
private static Cache stringCache;
private static Cache serializeCache;
private static Cache fieldCache;
private static Cache getterCache;
private static CacheManager cacheManager;
private static CacheManager getCacheManager () {
if (cacheManager == null ) {
if (System.getProperty("red5.root" ) != null ) {
try {
cacheManager = new CacheManager(Paths.get(System.getProperty("red5.root" ), "conf" , "ehcache.xml" ).toString());
} catch (CacheException e) {
cacheManager = constructDefault();
}
} else {
cacheManager = constructDefault();
}
}
return cacheManager;
}
private static CacheManager constructDefault () {
CacheManager manager = CacheManager.getInstance();
manager.addCacheIfAbsent("org.red5.io.amf.Output.stringCache" );
manager.addCacheIfAbsent("org.red5.io.amf.Output.getterCache" );
manager.addCacheIfAbsent("org.red5.io.amf.Output.fieldCache" );
manager.addCacheIfAbsent("org.red5.io.amf.Output.serializeCache" );
return manager;
}
protected IoBuffer buf;
public Output (IoBuffer buf) {
super ();
this .buf = buf;
}
@Override
public boolean isCustom (Object custom) {
return false ;
}
protected boolean checkWriteReference (Object obj) {
if (hasReference(obj)) {
writeReference(obj);
return true ;
}
return false ;
}
@Override
public void writeArray (Collection array) {
log.debug("writeArray - (collection source) array: {}" , array);
if (!checkWriteReference(array)) {
storeReference(array);
buf.put(AMF.TYPE_ARRAY);
buf.putInt(array.size());
for (Object item : array) {
Serializer.serialize(this , item);
}
}
}
@Override
public void writeArray (Object[] array) {
log.debug("writeArray - (array source) array: {}" , Arrays.asList(array));
if (array != null ) {
if (!checkWriteReference(array)) {
storeReference(array);
buf.put(AMF.TYPE_ARRAY);
buf.putInt(array.length);
for (Object item : array) {
Serializer.serialize(this , item);
}
}
} else {
writeNull();
}
}
@Override
public void writeArray (Object array) {
log.debug("writeArray - (object source) array: {}" , array);
if (array != null ) {
if (!checkWriteReference(array)) {
storeReference(array);
buf.put(AMF.TYPE_ARRAY);
final int length = Array.getLength(array);
buf.putInt(length);
for (int i = 0 ; i < length; i++) {
Serializer.serialize(this , Array.get(array, i));
}
}
} else {
writeNull();
}
}
@Override
public void writeMap (Map map) {
if (!checkWriteReference(map)) {
storeReference(map);
buf.put(AMF.TYPE_MIXED_ARRAY);
int maxInt = -1 ;
for (int i = 0 ; i < map.size(); i++) {
try {
if (!map.containsKey(i)) {
break ;
}
} catch (ClassCastException err) {
break ;
}
maxInt = i;
}
buf.putInt(maxInt + 1 );
for (Map.Entry entry : map.entrySet()) {
final String key = entry.getKey().toString();
if ("length" .equals(key)) {
continue ;
}
putString(key);
Serializer.serialize(this , entry.getValue());
}
if (maxInt >= 0 ) {
putString("length" );
Serializer.serialize(this , maxInt + 1 );
}
buf.put(AMF.END_OF_OBJECT_SEQUENCE);
}
}
@Override
public void writeMap (Collection array) {
if (!checkWriteReference(array)) {
storeReference(array);
buf.put(AMF.TYPE_MIXED_ARRAY);
buf.putInt(array.size() + 1 );
int idx = 0 ;
for (Object item : array) {
if (item != null ) {
putString(String.valueOf(idx++));
Serializer.serialize(this , item);
} else {
idx++;
}
}
putString("length" );
Serializer.serialize(this , array.size() + 1 );
buf.put(AMF.END_OF_OBJECT_SEQUENCE);
}
}
@Override
public void writeRecordSet (RecordSet recordset) {
if (!checkWriteReference(recordset)) {
storeReference(recordset);
buf.put(AMF.TYPE_CLASS_OBJECT);
putString("RecordSet" );
Map info = recordset.serialize();
putString("serverInfo" );
Serializer.serialize(this , info);
buf.put(AMF.END_OF_OBJECT_SEQUENCE);
}
}
@Override
public void writeBoolean (Boolean bol) {
buf.put(AMF.TYPE_BOOLEAN);
buf.put(bol ? AMF.VALUE_TRUE : AMF.VALUE_FALSE);
}
@Override
public void writeCustom (Object custom) {
}
@Override
public void writeDate (Date date) {
buf.put(AMF.TYPE_DATE);
buf.putDouble(date.getTime());
buf.putShort((short ) (TimeZone.getDefault().getRawOffset() / 60 / 1000 ));
}
@Override
public void writeNull () {
buf.put(AMF.TYPE_NULL);
}
@Override
public void writeNumber (Number num) {
buf.put(AMF.TYPE_NUMBER);
buf.putDouble(num.doubleValue());
}
@Override
public void writeReference (Object obj) {
log.debug("Write reference" );
buf.put(AMF.TYPE_REFERENCE);
buf.putShort(getReferenceId(obj));
}
@SuppressWarnings ({ "rawtypes" })
@Override
public void writeObject (Object object) {
if (!checkWriteReference(object)) {
storeReference(object);
BeanMap beanMap = new BeanMap(object);
Set attrs = beanMap.keySet();
log.trace("Bean map keys: {}" , attrs);
if (attrs.size() == 0 || (attrs.size() == 1 && beanMap.containsKey("class" ))) {
writeArbitraryObject(object);
return ;
}
Class objectClass = object.getClass();
if (!objectClass.isAnnotationPresent(Anonymous.class)) {
buf.put(AMF.TYPE_CLASS_OBJECT);
putString(buf, Serializer.getClassName(objectClass));
} else {
buf.put(AMF.TYPE_OBJECT);
}
for (Object key : attrs) {
String fieldName = key.toString();
log.debug("Field name: {} class: {}" , fieldName, objectClass);
Field field = getField(objectClass, fieldName);
Method getter = getGetter(objectClass, beanMap, fieldName);
if (!serializeField(objectClass, fieldName, field, getter)) {
continue ;
}
putString(buf, fieldName);
Serializer.serialize(this , field, getter, object, beanMap.get(key));
}
buf.put(AMF.END_OF_OBJECT_SEQUENCE);
}
}
@SuppressWarnings ("unchecked" )
protected boolean serializeField (Class objectClass, String keyName, Field field, Method getter) {
Element element = getSerializeCache().get(objectClass);
Map serializeMap = (element == null ? null : (Map) element.getObjectValue());
if (serializeMap == null ) {
serializeMap = new HashMap<>();
getSerializeCache().put(new Element(objectClass, serializeMap));
}
boolean serialize;
if (getSerializeCache().isKeyInCache(keyName)) {
serialize = serializeMap.get(keyName);
} else {
serialize = Serializer.serializeField(keyName, field, getter);
serializeMap.put(keyName, serialize);
}
return serialize;
}
@SuppressWarnings ("unchecked" )
protected Field getField (Class objectClass, String keyName) {
Element element = getFieldCache().get(objectClass);
Map fieldMap = (element == null ? null : (Map) element.getObjectValue());
if (fieldMap == null ) {
fieldMap = new HashMap();
getFieldCache().put(new Element(objectClass, fieldMap));
}
Field field = null ;
if (fieldMap.containsKey(keyName)) {
field = fieldMap.get(keyName);
} else {
for (Class clazz = objectClass; !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
Field[] fields = clazz.getDeclaredFields();
if (fields.length > 0 ) {
for (Field fld : fields) {
if (fld.getName().equals(keyName)) {
field = fld;
break ;
}
}
}
}
fieldMap.put(keyName, field);
}
return field;
}
@SuppressWarnings ("unchecked" )
protected Method getGetter (Class objectClass, BeanMap beanMap, String keyName) {
Element element = getGetterCache().get(objectClass);
Map getterMap = (element == null ? null : (Map) element.getObjectValue());
if (getterMap == null ) {
getterMap = new HashMap();
getGetterCache().put(new Element(objectClass, getterMap));
}
Method getter;
if (getterMap.containsKey(keyName)) {
getter = getterMap.get(keyName);
} else {
getter = beanMap.getReadMethod(keyName);
getterMap.put(keyName, getter);
}
return getter;
}
@Override
public void writeObject (Map map) {
if (!checkWriteReference(map)) {
storeReference(map);
buf.put(AMF.TYPE_OBJECT);
boolean isBeanMap = (map instanceof BeanMap);
for (Map.Entry entry : map.entrySet()) {
log.debug("Key: {} item: {}" , entry.getKey(), entry.getValue());
if (isBeanMap && "class" .equals(entry.getKey())) {
continue ;
}
putString(entry.getKey().toString());
Serializer.serialize(this , entry.getValue());
}
buf.put(AMF.END_OF_OBJECT_SEQUENCE);
}
}
protected void writeArbitraryObject (Object object) {
log.debug("writeObject" );
Class objectClass = object.getClass();
if (!objectClass.isAnnotationPresent(Anonymous.class)) {
buf.put(AMF.TYPE_CLASS_OBJECT);
putString(buf, Serializer.getClassName(objectClass));
} else {
buf.put(AMF.TYPE_OBJECT);
}
for (Field field : objectClass.getFields()) {
String fieldName = field.getName();
log.debug("Field: {} class: {}" , field, objectClass);
if (!serializeField(objectClass, fieldName, field, null )) {
continue ;
}
Object value;
try {
value = field.get(object);
} catch (IllegalAccessException err) {
continue ;
}
putString(buf, fieldName);
Serializer.serialize(this , field, null , object, value);
}
buf.put(AMF.END_OF_OBJECT_SEQUENCE);
}
@Override
public void writeString (String string) {
final byte [] encoded = encodeString(string);
final int len = encoded.length;
if (len < AMF.LONG_STRING_LENGTH) {
buf.put(AMF.TYPE_STRING);
buf.put((byte ) ((len >> 8 ) & 0xff ));
buf.put((byte ) (len & 0xff ));
} else {
buf.put(AMF.TYPE_LONG_STRING);
buf.putInt(len);
}
buf.put(encoded);
}
@Override
public void writeByteArray (ByteArray array) {
throw new RuntimeException("ByteArray objects not supported with AMF0" );
}
@Override
public void writeVectorInt (Vector vector) {
throw new RuntimeException("Vector objects not supported with AMF0" );
}
@Override
public void writeVectorUInt (Vector vector) {
throw new RuntimeException("Vector objects not supported with AMF0" );
}
@Override
public void writeVectorNumber (Vector vector) {
throw new RuntimeException("Vector objects not supported with AMF0" );
}
@Override
public void writeVectorObject (Vector vector) {
throw new RuntimeException("Vector objects not supported with AMF0" );
}
protected static byte [] encodeString(String string) {
Element element = getStringCache().get(string);
byte [] encoded = (element == null ? null : (byte []) element.getObjectValue());
if (encoded == null ) {
ByteBuffer buf = AMF.CHARSET.encode(string);
encoded = new byte [buf.remaining()];
buf.get(encoded);
getStringCache().put(new Element(string, encoded));
}
return encoded;
}
public static void putString (IoBuffer buf, String string) {
final byte [] encoded = encodeString(string);
if (encoded.length < AMF.LONG_STRING_LENGTH) {
buf.put((byte ) ((encoded.length >> 8 ) & 0xff ));
buf.put((byte ) (encoded.length & 0xff ));
} else {
buf.putInt(encoded.length);
}
buf.put(encoded);
}
@Override
public void putString (String string) {
putString(buf, string);
}
@Override
public void writeXML (Document xml) {
buf.put(AMF.TYPE_XML);
putString(XMLUtils.docToString(xml));
}
public void writeXML (String xml) {
buf.put(AMF.TYPE_XML);
putString(xml);
}
public IoBuffer buf () {
return this .buf;
}
public void reset () {
clearReferences();
}
protected static Cache getStringCache () {
if (stringCache == null ) {
stringCache = getCacheManager().getCache("org.red5.io.amf.Output.stringCache" );
}
return stringCache;
}
protected static Cache getSerializeCache () {
if (serializeCache == null ) {
serializeCache = getCacheManager().getCache("org.red5.io.amf.Output.serializeCache" );
}
return serializeCache;
}
protected static Cache getFieldCache () {
if (fieldCache == null ) {
fieldCache = getCacheManager().getCache("org.red5.io.amf.Output.fieldCache" );
}
return fieldCache;
}
protected static Cache getGetterCache () {
if (getterCache == null ) {
getterCache = getCacheManager().getCache("org.red5.io.amf.Output.getterCache" );
}
return getterCache;
}
public static void destroyCache () {
if (cacheManager != null ) {
cacheManager.shutdown();
fieldCache = null ;
getterCache = null ;
serializeCache = null ;
stringCache = null ;
}
}
}