|  |  |  | 
|---|
|  |  |  | package com.genersoft.iot.vmp.gb28181.utils; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson.JSONArray; | 
|---|
|  |  |  | import com.alibaba.fastjson.JSONObject; | 
|---|
|  |  |  | import com.alibaba.fastjson2.JSONArray; | 
|---|
|  |  |  | import com.alibaba.fastjson2.JSONObject; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.Device; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.TreeType; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.utils.DateUtil; | 
|---|
|  |  |  | import org.dom4j.Attribute; | 
|---|
|  |  |  | 
|---|
|  |  |  | import org.dom4j.io.SAXReader; | 
|---|
|  |  |  | import org.slf4j.Logger; | 
|---|
|  |  |  | import org.slf4j.LoggerFactory; | 
|---|
|  |  |  | import org.springframework.util.StringUtils; | 
|---|
|  |  |  | import org.springframework.util.ObjectUtils; | 
|---|
|  |  |  | import org.springframework.util.ReflectionUtils; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.sip.RequestEvent; | 
|---|
|  |  |  | import javax.sip.message.Request; | 
|---|
|  |  |  | import java.io.ByteArrayInputStream; | 
|---|
|  |  |  | import java.io.StringReader; | 
|---|
|  |  |  | import java.lang.reflect.Field; | 
|---|
|  |  |  | import java.lang.reflect.InvocationTargetException; | 
|---|
|  |  |  | import java.lang.reflect.ParameterizedType; | 
|---|
|  |  |  | import java.lang.reflect.Type; | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | // 如果是属性 | 
|---|
|  |  |  | for (Object o : element.attributes()) { | 
|---|
|  |  |  | Attribute attr = (Attribute) o; | 
|---|
|  |  |  | if (!StringUtils.isEmpty(attr.getValue())) { | 
|---|
|  |  |  | if (!ObjectUtils.isEmpty(attr.getValue())) { | 
|---|
|  |  |  | json.put("@" + attr.getName(), attr.getValue()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | List<Element> chdEl = element.elements(); | 
|---|
|  |  |  | if (chdEl.isEmpty() && !StringUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值 | 
|---|
|  |  |  | if (chdEl.isEmpty() && !ObjectUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值 | 
|---|
|  |  |  | json.put(element.getName(), element.getText()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { // 子元素没有子元素 | 
|---|
|  |  |  | for (Object o : element.attributes()) { | 
|---|
|  |  |  | Attribute attr = (Attribute) o; | 
|---|
|  |  |  | if (!StringUtils.isEmpty(attr.getValue())) { | 
|---|
|  |  |  | if (!ObjectUtils.isEmpty(attr.getValue())) { | 
|---|
|  |  |  | json.put("@" + attr.getName(), attr.getValue()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String channelId = channdelIdElement.getTextTrim(); | 
|---|
|  |  |  | if (StringUtils.isEmpty(channelId)) { | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(channelId)) { | 
|---|
|  |  |  | logger.warn("解析Catalog消息时发现缺少 DeviceID"); | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | ChannelType channelType = ChannelType.Other; | 
|---|
|  |  |  | if (channelId.length() <= 8) { | 
|---|
|  |  |  | channelType = ChannelType.CivilCode; | 
|---|
|  |  |  | deviceChannel.setHasAudio(false); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | if (channelId.length() == 20) { | 
|---|
|  |  |  | int code = Integer.parseInt(channelId.substring(10, 13)); | 
|---|
|  |  |  | switch (code){ | 
|---|
|  |  |  | case 215: | 
|---|
|  |  |  | channelType = ChannelType.BusinessGroup; | 
|---|
|  |  |  | deviceChannel.setHasAudio(false); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 216: | 
|---|
|  |  |  | channelType = ChannelType.VirtualOrganization; | 
|---|
|  |  |  | deviceChannel.setHasAudio(false); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case 136: | 
|---|
|  |  |  | case 137: | 
|---|
|  |  |  | case 138: | 
|---|
|  |  |  | deviceChannel.setHasAudio(true); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | default: | 
|---|
|  |  |  | deviceChannel.setHasAudio(false); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | deviceChannel.setParentId(parentId); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 兼容设备通道信息中自己为自己父节点的情况 | 
|---|
|  |  |  | if (deviceChannel.getParentId().equals(deviceChannel.getChannelId())) { | 
|---|
|  |  |  | deviceChannel.setParentId(null); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | deviceChannel.setBusinessGroupId(businessGroupID); | 
|---|
|  |  |  | if (channelType.equals(ChannelType.BusinessGroup) || channelType.equals(ChannelType.VirtualOrganization)) { | 
|---|
|  |  |  | 
|---|
|  |  |  | // 识别自带的目录标识 | 
|---|
|  |  |  | String parental = XmlUtil.getText(itemDevice, "Parental"); | 
|---|
|  |  |  | // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1 | 
|---|
|  |  |  | if (!StringUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) { | 
|---|
|  |  |  | if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) { | 
|---|
|  |  |  | deviceChannel.setParental(0); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | deviceChannel.setParental(1); | 
|---|
|  |  |  | 
|---|
|  |  |  | deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay"); | 
|---|
|  |  |  | if (StringUtils.isEmpty(safetyWay)) { | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(safetyWay)) { | 
|---|
|  |  |  | deviceChannel.setSafetyWay(0); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | deviceChannel.setSafetyWay(Integer.parseInt(safetyWay)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String registerWay = XmlUtil.getText(itemDevice, "RegisterWay"); | 
|---|
|  |  |  | if (StringUtils.isEmpty(registerWay)) { | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(registerWay)) { | 
|---|
|  |  |  | deviceChannel.setRegisterWay(1); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | deviceChannel.setRegisterWay(Integer.parseInt(registerWay)); | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | deviceChannel.setLatitude(0.00); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | deviceChannel.setGpsTime(DateUtil.getNow()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return deviceChannel; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 新增方法支持内部嵌套 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param element xmlElement | 
|---|
|  |  |  | * @param clazz 结果类 | 
|---|
|  |  |  | * @param <T> 泛型 | 
|---|
|  |  |  | * @return 结果对象 | 
|---|
|  |  |  | * @throws NoSuchMethodException | 
|---|
|  |  |  | * @throws InvocationTargetException | 
|---|
|  |  |  | * @throws InstantiationException | 
|---|
|  |  |  | * @throws IllegalAccessException | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static <T> T loadElement(Element element, Class<T> clazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { | 
|---|
|  |  |  | Field[] fields = clazz.getDeclaredFields(); | 
|---|
|  |  |  | T t = clazz.getDeclaredConstructor().newInstance(); | 
|---|
|  |  |  | for (Field field : fields) { | 
|---|
|  |  |  | ReflectionUtils.makeAccessible(field); | 
|---|
|  |  |  | MessageElement annotation = field.getAnnotation(MessageElement.class); | 
|---|
|  |  |  | if (annotation == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String value = annotation.value(); | 
|---|
|  |  |  | String subVal = annotation.subVal(); | 
|---|
|  |  |  | Element element1 = element.element(value); | 
|---|
|  |  |  | if (element1 == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if ("".equals(subVal)) { | 
|---|
|  |  |  | // 无下级数据 | 
|---|
|  |  |  | Object fieldVal = element1.isTextOnly() ? element1.getText() : loadElement(element1, field.getType()); | 
|---|
|  |  |  | Object o = simpleTypeDeal(field.getType(), fieldVal); | 
|---|
|  |  |  | ReflectionUtils.setField(field, t,  o); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | // 存在下级数据 | 
|---|
|  |  |  | ArrayList<Object> list = new ArrayList<>(); | 
|---|
|  |  |  | Type genericType = field.getGenericType(); | 
|---|
|  |  |  | if (!(genericType instanceof ParameterizedType)) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Class<?> aClass = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0]; | 
|---|
|  |  |  | for (Element element2 : element1.elements(subVal)) { | 
|---|
|  |  |  | list.add(loadElement(element2, aClass)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | ReflectionUtils.setField(field, t, list); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return t; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 简单类型处理 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param tClass | 
|---|
|  |  |  | * @param val | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private static Object simpleTypeDeal(Class<?> tClass, Object val) { | 
|---|
|  |  |  | if (tClass.equals(String.class)) { | 
|---|
|  |  |  | return val.toString(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (tClass.equals(Integer.class)) { | 
|---|
|  |  |  | return Integer.valueOf(val.toString()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (tClass.equals(Double.class)) { | 
|---|
|  |  |  | return Double.valueOf(val.toString()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (tClass.equals(Long.class)) { | 
|---|
|  |  |  | return Long.valueOf(val.toString()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return val; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|