|
|
@@ -0,0 +1,443 @@
|
|
|
+package com.steerinfo.meterwork.meterworkmonitor.rtdb;
|
|
|
+
|
|
|
+import com.steerinfo.meterwork.meterworkmonitor.model.MeterWorkMonitor;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * MeterWorkMonitor ↔ Tarantool tuple(66 业务字段 + _dirty + _updated_at)。
|
|
|
+ */
|
|
|
+public final class MeterWorkMonitorTupleCodec {
|
|
|
+
|
|
|
+ public static final int FIELD_COUNT = 68;
|
|
|
+ public static final int IDX_POINT_NO = 1;
|
|
|
+ public static final int IDX_LAST_TIME = 30;
|
|
|
+ public static final int IDX_DIRTY = 67;
|
|
|
+ public static final int IDX_UPDATED_AT = 68;
|
|
|
+
|
|
|
+ private MeterWorkMonitorTupleCodec() {
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<Object> toTuple(MeterWorkMonitor m, boolean dirty) {
|
|
|
+ List<Object> t = new ArrayList<>(FIELD_COUNT);
|
|
|
+ t.add(nullToEmpty(m.getPointNo()));
|
|
|
+ t.add(nullToEmpty(m.getPointName()));
|
|
|
+ t.add(nullToEmpty(m.getValidWgt()));
|
|
|
+ t.add(nullToEmpty(m.getValidCarno()));
|
|
|
+ t.add(nullToEmpty(m.getValidTareTime()));
|
|
|
+ t.add(nullToEmpty(m.getValidTimeInterval()));
|
|
|
+ t.add(nullToEmpty(m.getValidParkStatus()));
|
|
|
+ t.add(nullToEmpty(m.getValidExceedWgt()));
|
|
|
+ t.add(nullToEmpty(m.getValidPredictionDiff()));
|
|
|
+ t.add(nullToEmpty(m.getValidFlag()));
|
|
|
+ t.add(nullToEmpty(m.getValidMatTime()));
|
|
|
+ t.add(nullToEmpty(m.getCarMonitor()));
|
|
|
+ t.add(numOrZero(m.getCarMonitorLvl()));
|
|
|
+ t.add(nullToEmpty(m.getIsHelp()));
|
|
|
+ t.add(nullToEmpty(m.getIsTakeOver()));
|
|
|
+ t.add(nullToEmpty(m.getLedWriter()));
|
|
|
+ t.add(numOrZero(m.getPrintNum()));
|
|
|
+ t.add(nullToEmpty(m.getCollectionCode()));
|
|
|
+ t.add(nullToEmpty(m.getIsOverWgt()));
|
|
|
+ t.add(nullToEmpty(m.getUserNo()));
|
|
|
+ t.add(nullToEmpty(m.getMonitorUserNo()));
|
|
|
+ t.add(nullToEmpty(m.getSetCar()));
|
|
|
+ t.add(nullToEmpty(m.getLedKeep()));
|
|
|
+ t.add(nullToEmpty(m.getRfidCar()));
|
|
|
+ t.add(nullToEmpty(m.getPhotoCar()));
|
|
|
+ t.add(nullToEmpty(m.getScanCar()));
|
|
|
+ t.add(nullToEmpty(m.getEditCar()));
|
|
|
+ t.add(nullToEmpty(m.getCarErr()));
|
|
|
+ t.add(nullToEmpty(m.getWgtErr()));
|
|
|
+ t.add(dateToEpoch(m.getLastTime()));
|
|
|
+ t.add(nullToEmpty(m.getStopOverTime()));
|
|
|
+ t.add(nullToEmpty(m.getMsgInfo()));
|
|
|
+ t.add(m.getWgt() == null ? 0L : m.getWgt());
|
|
|
+ t.add(nullToEmpty(m.getIsRemote()));
|
|
|
+ t.add(nullToEmpty(m.getWeighInstrumentModel()));
|
|
|
+ t.add(nullToEmpty(m.getWeighInstrumentParam()));
|
|
|
+ t.add(nullToEmpty(m.getMoxaIp()));
|
|
|
+ t.add(nullToEmpty(m.getMoxaPort()));
|
|
|
+ t.add(nullToEmpty(m.getValidLianda()));
|
|
|
+ t.add(nullToEmpty(m.getIsOpenScanning()));
|
|
|
+ t.add(nullToEmpty(m.getValidIsPre()));
|
|
|
+ t.add(nullToEmpty(m.getUserIp()));
|
|
|
+ t.add(nullToEmpty(m.getPowerState()));
|
|
|
+ t.add(nullToEmpty(m.getDvrState()));
|
|
|
+ t.add(nullToEmpty(m.getMoxaState()));
|
|
|
+ t.add(nullToEmpty(m.getPlcState()));
|
|
|
+ t.add(nullToEmpty(m.getLeftInfraredRayState()));
|
|
|
+ t.add(nullToEmpty(m.getRightInfraredRayState()));
|
|
|
+ t.add(nullToEmpty(m.getAmplifierState()));
|
|
|
+ t.add(nullToEmpty(m.getLampState()));
|
|
|
+ t.add(nullToEmpty(m.getSpotTypeNo()));
|
|
|
+ t.add(nullToEmpty(m.getRedGreenLightState()));
|
|
|
+ t.add(nullToEmpty(m.getFrontInfraredRayState()));
|
|
|
+ t.add(nullToEmpty(m.getRearInfraredRayState()));
|
|
|
+ t.add(nullToEmpty(m.getRfidState()));
|
|
|
+ t.add(nullToEmpty(m.getValidArea()));
|
|
|
+ t.add(nullToEmpty(m.getWeightStatus()));
|
|
|
+ t.add(nullToEmpty(m.getFerroalloyConfirm()));
|
|
|
+ t.add(nullToEmpty(m.getFerroalloyResult()));
|
|
|
+ t.add(nullToEmpty(m.getZeroState()));
|
|
|
+ t.add(numOrZero(m.getZeroWeight()));
|
|
|
+ t.add(nullToEmpty(m.getIsZeroState()));
|
|
|
+ t.add(nullToEmpty(m.getIsValidScan()));
|
|
|
+ t.add(nullToEmpty(m.getIsEnableSound()));
|
|
|
+ t.add(nullToEmpty(m.getPhotoCar2()));
|
|
|
+ t.add(dirty);
|
|
|
+ t.add(System.currentTimeMillis());
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static MeterWorkMonitor fromTuple(List<?> t) {
|
|
|
+ if (t == null || t.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ MeterWorkMonitor m = new MeterWorkMonitor();
|
|
|
+ m.setPointNo(asString(t, 0));
|
|
|
+ m.setPointName(asString(t, 1));
|
|
|
+ m.setValidWgt(asString(t, 2));
|
|
|
+ m.setValidCarno(asString(t, 3));
|
|
|
+ m.setValidTareTime(asString(t, 4));
|
|
|
+ m.setValidTimeInterval(asString(t, 5));
|
|
|
+ m.setValidParkStatus(asString(t, 6));
|
|
|
+ m.setValidExceedWgt(asString(t, 7));
|
|
|
+ m.setValidPredictionDiff(asString(t, 8));
|
|
|
+ m.setValidFlag(asString(t, 9));
|
|
|
+ m.setValidMatTime(asString(t, 10));
|
|
|
+ m.setCarMonitor(asString(t, 11));
|
|
|
+ m.setCarMonitorLvl(asShort(t, 12));
|
|
|
+ m.setIsHelp(asString(t, 13));
|
|
|
+ m.setIsTakeOver(asString(t, 14));
|
|
|
+ m.setLedWriter(asString(t, 15));
|
|
|
+ m.setPrintNum(asShort(t, 16));
|
|
|
+ m.setCollectionCode(asString(t, 17));
|
|
|
+ m.setIsOverWgt(asString(t, 18));
|
|
|
+ m.setUserNo(asString(t, 19));
|
|
|
+ m.setMonitorUserNo(asString(t, 20));
|
|
|
+ m.setSetCar(asString(t, 21));
|
|
|
+ m.setLedKeep(asString(t, 22));
|
|
|
+ m.setRfidCar(asString(t, 23));
|
|
|
+ m.setPhotoCar(asString(t, 24));
|
|
|
+ m.setScanCar(asString(t, 25));
|
|
|
+ m.setEditCar(asString(t, 26));
|
|
|
+ m.setCarErr(asString(t, 27));
|
|
|
+ m.setWgtErr(asString(t, 28));
|
|
|
+ m.setLastTime(asDate(t, 29));
|
|
|
+ m.setStopOverTime(asString(t, 30));
|
|
|
+ m.setMsgInfo(asString(t, 31));
|
|
|
+ m.setWgt(asLong(t, 32));
|
|
|
+ m.setIsRemote(asString(t, 33));
|
|
|
+ m.setWeighInstrumentModel(asString(t, 34));
|
|
|
+ m.setWeighInstrumentParam(asString(t, 35));
|
|
|
+ m.setMoxaIp(asString(t, 36));
|
|
|
+ m.setMoxaPort(asString(t, 37));
|
|
|
+ m.setValidLianda(asString(t, 38));
|
|
|
+ m.setIsOpenScanning(asString(t, 39));
|
|
|
+ m.setValidIsPre(asString(t, 40));
|
|
|
+ m.setUserIp(asString(t, 41));
|
|
|
+ m.setPowerState(asString(t, 42));
|
|
|
+ m.setDvrState(asString(t, 43));
|
|
|
+ m.setMoxaState(asString(t, 44));
|
|
|
+ m.setPlcState(asString(t, 45));
|
|
|
+ m.setLeftInfraredRayState(asString(t, 46));
|
|
|
+ m.setRightInfraredRayState(asString(t, 47));
|
|
|
+ m.setAmplifierState(asString(t, 48));
|
|
|
+ m.setLampState(asString(t, 49));
|
|
|
+ m.setSpotTypeNo(asString(t, 50));
|
|
|
+ m.setRedGreenLightState(asString(t, 51));
|
|
|
+ m.setFrontInfraredRayState(asString(t, 52));
|
|
|
+ m.setRearInfraredRayState(asString(t, 53));
|
|
|
+ m.setRfidState(asString(t, 54));
|
|
|
+ m.setValidArea(asString(t, 55));
|
|
|
+ m.setWeightStatus(asString(t, 56));
|
|
|
+ m.setFerroalloyConfirm(asString(t, 57));
|
|
|
+ m.setFerroalloyResult(asString(t, 58));
|
|
|
+ m.setZeroState(asString(t, 59));
|
|
|
+ m.setZeroWeight(asShort(t, 60));
|
|
|
+ m.setIsZeroState(asString(t, 61));
|
|
|
+ m.setIsValidScan(asString(t, 62));
|
|
|
+ m.setIsEnableSound(asString(t, 63));
|
|
|
+ m.setPhotoCar2(asString(t, 64));
|
|
|
+ return m;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean isDirty(List<?> t) {
|
|
|
+ if (t == null || t.size() < IDX_DIRTY) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ Object v = t.get(IDX_DIRTY - 1);
|
|
|
+ return Boolean.TRUE.equals(v) || "true".equalsIgnoreCase(String.valueOf(v));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将 patch 中非空字段合并到 base(selective update 语义)。
|
|
|
+ */
|
|
|
+ public static void mergeNonNull(MeterWorkMonitor base, MeterWorkMonitor patch) {
|
|
|
+ if (patch.getPointName() != null) {
|
|
|
+ base.setPointName(patch.getPointName());
|
|
|
+ }
|
|
|
+ if (patch.getValidWgt() != null) {
|
|
|
+ base.setValidWgt(patch.getValidWgt());
|
|
|
+ }
|
|
|
+ if (patch.getValidCarno() != null) {
|
|
|
+ base.setValidCarno(patch.getValidCarno());
|
|
|
+ }
|
|
|
+ if (patch.getValidTareTime() != null) {
|
|
|
+ base.setValidTareTime(patch.getValidTareTime());
|
|
|
+ }
|
|
|
+ if (patch.getValidTimeInterval() != null) {
|
|
|
+ base.setValidTimeInterval(patch.getValidTimeInterval());
|
|
|
+ }
|
|
|
+ if (patch.getValidParkStatus() != null) {
|
|
|
+ base.setValidParkStatus(patch.getValidParkStatus());
|
|
|
+ }
|
|
|
+ if (patch.getValidExceedWgt() != null) {
|
|
|
+ base.setValidExceedWgt(patch.getValidExceedWgt());
|
|
|
+ }
|
|
|
+ if (patch.getValidPredictionDiff() != null) {
|
|
|
+ base.setValidPredictionDiff(patch.getValidPredictionDiff());
|
|
|
+ }
|
|
|
+ if (patch.getValidFlag() != null) {
|
|
|
+ base.setValidFlag(patch.getValidFlag());
|
|
|
+ }
|
|
|
+ if (patch.getValidMatTime() != null) {
|
|
|
+ base.setValidMatTime(patch.getValidMatTime());
|
|
|
+ }
|
|
|
+ if (patch.getCarMonitor() != null) {
|
|
|
+ base.setCarMonitor(patch.getCarMonitor());
|
|
|
+ }
|
|
|
+ if (patch.getCarMonitorLvl() != null) {
|
|
|
+ base.setCarMonitorLvl(patch.getCarMonitorLvl());
|
|
|
+ }
|
|
|
+ if (patch.getIsHelp() != null) {
|
|
|
+ base.setIsHelp(patch.getIsHelp());
|
|
|
+ }
|
|
|
+ if (patch.getIsTakeOver() != null) {
|
|
|
+ base.setIsTakeOver(patch.getIsTakeOver());
|
|
|
+ }
|
|
|
+ if (patch.getLedWriter() != null) {
|
|
|
+ base.setLedWriter(patch.getLedWriter());
|
|
|
+ }
|
|
|
+ if (patch.getPrintNum() != null) {
|
|
|
+ base.setPrintNum(patch.getPrintNum());
|
|
|
+ }
|
|
|
+ if (patch.getCollectionCode() != null) {
|
|
|
+ base.setCollectionCode(patch.getCollectionCode());
|
|
|
+ }
|
|
|
+ if (patch.getIsOverWgt() != null) {
|
|
|
+ base.setIsOverWgt(patch.getIsOverWgt());
|
|
|
+ }
|
|
|
+ if (patch.getUserNo() != null) {
|
|
|
+ base.setUserNo(patch.getUserNo());
|
|
|
+ }
|
|
|
+ if (patch.getMonitorUserNo() != null) {
|
|
|
+ base.setMonitorUserNo(patch.getMonitorUserNo());
|
|
|
+ }
|
|
|
+ if (patch.getSetCar() != null) {
|
|
|
+ base.setSetCar(patch.getSetCar());
|
|
|
+ }
|
|
|
+ if (patch.getLedKeep() != null) {
|
|
|
+ base.setLedKeep(patch.getLedKeep());
|
|
|
+ }
|
|
|
+ if (patch.getRfidCar() != null) {
|
|
|
+ base.setRfidCar(patch.getRfidCar());
|
|
|
+ }
|
|
|
+ if (patch.getPhotoCar() != null) {
|
|
|
+ base.setPhotoCar(patch.getPhotoCar());
|
|
|
+ }
|
|
|
+ if (patch.getScanCar() != null) {
|
|
|
+ base.setScanCar(patch.getScanCar());
|
|
|
+ }
|
|
|
+ if (patch.getEditCar() != null) {
|
|
|
+ base.setEditCar(patch.getEditCar());
|
|
|
+ }
|
|
|
+ if (patch.getCarErr() != null) {
|
|
|
+ base.setCarErr(patch.getCarErr());
|
|
|
+ }
|
|
|
+ if (patch.getWgtErr() != null) {
|
|
|
+ base.setWgtErr(patch.getWgtErr());
|
|
|
+ }
|
|
|
+ if (patch.getLastTime() != null) {
|
|
|
+ base.setLastTime(patch.getLastTime());
|
|
|
+ }
|
|
|
+ if (patch.getStopOverTime() != null) {
|
|
|
+ base.setStopOverTime(patch.getStopOverTime());
|
|
|
+ }
|
|
|
+ if (patch.getMsgInfo() != null) {
|
|
|
+ base.setMsgInfo(patch.getMsgInfo());
|
|
|
+ }
|
|
|
+ if (patch.getWgt() != null) {
|
|
|
+ base.setWgt(patch.getWgt());
|
|
|
+ }
|
|
|
+ if (patch.getIsRemote() != null) {
|
|
|
+ base.setIsRemote(patch.getIsRemote());
|
|
|
+ }
|
|
|
+ if (patch.getWeighInstrumentModel() != null) {
|
|
|
+ base.setWeighInstrumentModel(patch.getWeighInstrumentModel());
|
|
|
+ }
|
|
|
+ if (patch.getWeighInstrumentParam() != null) {
|
|
|
+ base.setWeighInstrumentParam(patch.getWeighInstrumentParam());
|
|
|
+ }
|
|
|
+ if (patch.getMoxaIp() != null) {
|
|
|
+ base.setMoxaIp(patch.getMoxaIp());
|
|
|
+ }
|
|
|
+ if (patch.getMoxaPort() != null) {
|
|
|
+ base.setMoxaPort(patch.getMoxaPort());
|
|
|
+ }
|
|
|
+ if (patch.getValidLianda() != null) {
|
|
|
+ base.setValidLianda(patch.getValidLianda());
|
|
|
+ }
|
|
|
+ if (patch.getIsOpenScanning() != null) {
|
|
|
+ base.setIsOpenScanning(patch.getIsOpenScanning());
|
|
|
+ }
|
|
|
+ if (patch.getValidIsPre() != null) {
|
|
|
+ base.setValidIsPre(patch.getValidIsPre());
|
|
|
+ }
|
|
|
+ if (patch.getUserIp() != null) {
|
|
|
+ base.setUserIp(patch.getUserIp());
|
|
|
+ }
|
|
|
+ if (patch.getPowerState() != null) {
|
|
|
+ base.setPowerState(patch.getPowerState());
|
|
|
+ }
|
|
|
+ if (patch.getDvrState() != null) {
|
|
|
+ base.setDvrState(patch.getDvrState());
|
|
|
+ }
|
|
|
+ if (patch.getMoxaState() != null) {
|
|
|
+ base.setMoxaState(patch.getMoxaState());
|
|
|
+ }
|
|
|
+ if (patch.getPlcState() != null) {
|
|
|
+ base.setPlcState(patch.getPlcState());
|
|
|
+ }
|
|
|
+ if (patch.getLeftInfraredRayState() != null) {
|
|
|
+ base.setLeftInfraredRayState(patch.getLeftInfraredRayState());
|
|
|
+ }
|
|
|
+ if (patch.getRightInfraredRayState() != null) {
|
|
|
+ base.setRightInfraredRayState(patch.getRightInfraredRayState());
|
|
|
+ }
|
|
|
+ if (patch.getAmplifierState() != null) {
|
|
|
+ base.setAmplifierState(patch.getAmplifierState());
|
|
|
+ }
|
|
|
+ if (patch.getLampState() != null) {
|
|
|
+ base.setLampState(patch.getLampState());
|
|
|
+ }
|
|
|
+ if (patch.getSpotTypeNo() != null) {
|
|
|
+ base.setSpotTypeNo(patch.getSpotTypeNo());
|
|
|
+ }
|
|
|
+ if (patch.getRedGreenLightState() != null) {
|
|
|
+ base.setRedGreenLightState(patch.getRedGreenLightState());
|
|
|
+ }
|
|
|
+ if (patch.getFrontInfraredRayState() != null) {
|
|
|
+ base.setFrontInfraredRayState(patch.getFrontInfraredRayState());
|
|
|
+ }
|
|
|
+ if (patch.getRearInfraredRayState() != null) {
|
|
|
+ base.setRearInfraredRayState(patch.getRearInfraredRayState());
|
|
|
+ }
|
|
|
+ if (patch.getRfidState() != null) {
|
|
|
+ base.setRfidState(patch.getRfidState());
|
|
|
+ }
|
|
|
+ if (patch.getValidArea() != null) {
|
|
|
+ base.setValidArea(patch.getValidArea());
|
|
|
+ }
|
|
|
+ if (patch.getWeightStatus() != null) {
|
|
|
+ base.setWeightStatus(patch.getWeightStatus());
|
|
|
+ }
|
|
|
+ if (patch.getFerroalloyConfirm() != null) {
|
|
|
+ base.setFerroalloyConfirm(patch.getFerroalloyConfirm());
|
|
|
+ }
|
|
|
+ if (patch.getFerroalloyResult() != null) {
|
|
|
+ base.setFerroalloyResult(patch.getFerroalloyResult());
|
|
|
+ }
|
|
|
+ if (patch.getZeroState() != null) {
|
|
|
+ base.setZeroState(patch.getZeroState());
|
|
|
+ }
|
|
|
+ if (patch.getZeroWeight() != null) {
|
|
|
+ base.setZeroWeight(patch.getZeroWeight());
|
|
|
+ }
|
|
|
+ if (patch.getIsZeroState() != null) {
|
|
|
+ base.setIsZeroState(patch.getIsZeroState());
|
|
|
+ }
|
|
|
+ if (patch.getIsValidScan() != null) {
|
|
|
+ base.setIsValidScan(patch.getIsValidScan());
|
|
|
+ }
|
|
|
+ if (patch.getIsEnableSound() != null) {
|
|
|
+ base.setIsEnableSound(patch.getIsEnableSound());
|
|
|
+ }
|
|
|
+ if (patch.getPhotoCar2() != null) {
|
|
|
+ base.setPhotoCar2(patch.getPhotoCar2());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String nullToEmpty(String s) {
|
|
|
+ return s == null ? "" : s;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Number numOrZero(Number n) {
|
|
|
+ return n == null ? 0 : n;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Long dateToEpoch(Date d) {
|
|
|
+ return d == null ? null : d.getTime();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Object at(List<?> t, int idx) {
|
|
|
+ return idx < t.size() ? t.get(idx) : null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String asString(List<?> t, int idx) {
|
|
|
+ Object v = at(t, idx);
|
|
|
+ if (v == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ String s = String.valueOf(v);
|
|
|
+ return s.isEmpty() ? null : s;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Short asShort(List<?> t, int idx) {
|
|
|
+ Object v = at(t, idx);
|
|
|
+ if (v == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (v instanceof Number) {
|
|
|
+ return ((Number) v).shortValue();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return Short.valueOf(String.valueOf(v));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Long asLong(List<?> t, int idx) {
|
|
|
+ Object v = at(t, idx);
|
|
|
+ if (v == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (v instanceof Number) {
|
|
|
+ return ((Number) v).longValue();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return Long.valueOf(String.valueOf(v));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Date asDate(List<?> t, int idx) {
|
|
|
+ Object v = at(t, idx);
|
|
|
+ if (v == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (v instanceof Date) {
|
|
|
+ return (Date) v;
|
|
|
+ }
|
|
|
+ if (v instanceof Number) {
|
|
|
+ long epoch = ((Number) v).longValue();
|
|
|
+ return epoch <= 0 ? null : new Date(epoch);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+}
|