mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
722feeb02b
Summary: Changelog: [General] [Fixed] - License header cleanup Reviewed By: yungsters Differential Revision: D17952695 fbshipit-source-id: 81aa607612ba1357ef7814ef20371335151afe7e
173 lines
6.2 KiB
Java
173 lines
6.2 KiB
Java
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
package com.facebook.react.uimanager;
|
|
|
|
import android.view.View;
|
|
import com.facebook.common.logging.FLog;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
|
|
public class ViewManagerPropertyUpdater {
|
|
public interface Settable {
|
|
void getProperties(Map<String, String> props);
|
|
}
|
|
|
|
public interface ViewManagerSetter<T extends ViewManager, V extends View> extends Settable {
|
|
void setProperty(T manager, V view, String name, Object value);
|
|
}
|
|
|
|
public interface ShadowNodeSetter<T extends ReactShadowNode> extends Settable {
|
|
void setProperty(T node, String name, Object value);
|
|
}
|
|
|
|
private static final String TAG = "ViewManagerPropertyUpdater";
|
|
|
|
private static final Map<Class<?>, ViewManagerSetter<?, ?>> VIEW_MANAGER_SETTER_MAP =
|
|
new HashMap<>();
|
|
private static final Map<Class<?>, ShadowNodeSetter<?>> SHADOW_NODE_SETTER_MAP = new HashMap<>();
|
|
|
|
public static void clear() {
|
|
ViewManagersPropertyCache.clear();
|
|
VIEW_MANAGER_SETTER_MAP.clear();
|
|
SHADOW_NODE_SETTER_MAP.clear();
|
|
}
|
|
|
|
public static <T extends ViewManagerDelegate<V>, V extends View> void updateProps(
|
|
T delegate, V v, ReactStylesDiffMap props) {
|
|
Iterator<Map.Entry<String, Object>> iterator = props.mBackingMap.getEntryIterator();
|
|
while (iterator.hasNext()) {
|
|
Map.Entry<String, Object> entry = iterator.next();
|
|
delegate.setProperty(v, entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
|
|
public static <T extends ViewManager, V extends View> void updateProps(
|
|
T manager, V v, ReactStylesDiffMap props) {
|
|
ViewManagerSetter<T, V> setter = findManagerSetter(manager.getClass());
|
|
Iterator<Map.Entry<String, Object>> iterator = props.mBackingMap.getEntryIterator();
|
|
while (iterator.hasNext()) {
|
|
Map.Entry<String, Object> entry = iterator.next();
|
|
setter.setProperty(manager, v, entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
|
|
public static <T extends ReactShadowNode> void updateProps(T node, ReactStylesDiffMap props) {
|
|
ShadowNodeSetter<T> setter = findNodeSetter(node.getClass());
|
|
Iterator<Map.Entry<String, Object>> iterator = props.mBackingMap.getEntryIterator();
|
|
while (iterator.hasNext()) {
|
|
Map.Entry<String, Object> entry = iterator.next();
|
|
setter.setProperty(node, entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
|
|
public static Map<String, String> getNativeProps(
|
|
Class<? extends ViewManager> viewManagerTopClass,
|
|
Class<? extends ReactShadowNode> shadowNodeTopClass) {
|
|
Map<String, String> props = new HashMap<>();
|
|
findManagerSetter(viewManagerTopClass).getProperties(props);
|
|
findNodeSetter(shadowNodeTopClass).getProperties(props);
|
|
return props;
|
|
}
|
|
|
|
private static <T extends ViewManager, V extends View> ViewManagerSetter<T, V> findManagerSetter(
|
|
Class<? extends ViewManager> managerClass) {
|
|
@SuppressWarnings("unchecked")
|
|
ViewManagerSetter<T, V> setter =
|
|
(ViewManagerSetter<T, V>) VIEW_MANAGER_SETTER_MAP.get(managerClass);
|
|
if (setter == null) {
|
|
setter = findGeneratedSetter(managerClass);
|
|
if (setter == null) {
|
|
setter = new FallbackViewManagerSetter<>(managerClass);
|
|
}
|
|
VIEW_MANAGER_SETTER_MAP.put(managerClass, setter);
|
|
}
|
|
|
|
return setter;
|
|
}
|
|
|
|
private static <T extends ReactShadowNode> ShadowNodeSetter<T> findNodeSetter(
|
|
Class<? extends ReactShadowNode> nodeClass) {
|
|
@SuppressWarnings("unchecked")
|
|
ShadowNodeSetter<T> setter = (ShadowNodeSetter<T>) SHADOW_NODE_SETTER_MAP.get(nodeClass);
|
|
if (setter == null) {
|
|
setter = findGeneratedSetter(nodeClass);
|
|
if (setter == null) {
|
|
setter = new FallbackShadowNodeSetter<>(nodeClass);
|
|
}
|
|
SHADOW_NODE_SETTER_MAP.put(nodeClass, setter);
|
|
}
|
|
|
|
return setter;
|
|
}
|
|
|
|
private static <T> T findGeneratedSetter(Class<?> cls) {
|
|
String clsName = cls.getName();
|
|
try {
|
|
Class<?> setterClass = Class.forName(clsName + "$$PropsSetter");
|
|
//noinspection unchecked
|
|
return (T) setterClass.newInstance();
|
|
} catch (ClassNotFoundException e) {
|
|
FLog.w(TAG, "Could not find generated setter for " + cls);
|
|
return null;
|
|
} catch (InstantiationException | IllegalAccessException e) {
|
|
throw new RuntimeException("Unable to instantiate methods getter for " + clsName, e);
|
|
}
|
|
}
|
|
|
|
private static class FallbackViewManagerSetter<T extends ViewManager, V extends View>
|
|
implements ViewManagerSetter<T, V> {
|
|
private final Map<String, ViewManagersPropertyCache.PropSetter> mPropSetters;
|
|
|
|
private FallbackViewManagerSetter(Class<? extends ViewManager> viewManagerClass) {
|
|
mPropSetters =
|
|
ViewManagersPropertyCache.getNativePropSettersForViewManagerClass(viewManagerClass);
|
|
}
|
|
|
|
@Override
|
|
public void setProperty(T manager, V v, String name, Object value) {
|
|
ViewManagersPropertyCache.PropSetter setter = mPropSetters.get(name);
|
|
if (setter != null) {
|
|
setter.updateViewProp(manager, v, value);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void getProperties(Map<String, String> props) {
|
|
for (ViewManagersPropertyCache.PropSetter setter : mPropSetters.values()) {
|
|
props.put(setter.getPropName(), setter.getPropType());
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class FallbackShadowNodeSetter<T extends ReactShadowNode>
|
|
implements ShadowNodeSetter<T> {
|
|
private final Map<String, ViewManagersPropertyCache.PropSetter> mPropSetters;
|
|
|
|
private FallbackShadowNodeSetter(Class<? extends ReactShadowNode> shadowNodeClass) {
|
|
mPropSetters =
|
|
ViewManagersPropertyCache.getNativePropSettersForShadowNodeClass(shadowNodeClass);
|
|
}
|
|
|
|
@Override
|
|
public void setProperty(ReactShadowNode node, String name, Object value) {
|
|
ViewManagersPropertyCache.PropSetter setter = mPropSetters.get(name);
|
|
if (setter != null) {
|
|
setter.updateShadowNodeProp(node, value);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void getProperties(Map<String, String> props) {
|
|
for (ViewManagersPropertyCache.PropSetter setter : mPropSetters.values()) {
|
|
props.put(setter.getPropName(), setter.getPropType());
|
|
}
|
|
}
|
|
}
|
|
}
|