ソースを参照

Support updatePart panel instance

sunyj 8 年 前
コミット
4b69357f49

+ 2 - 1
kanban-console/src/main/java/com/uas/kanban/model/PanelInstance.java

@@ -11,6 +11,7 @@ import com.uas.kanban.util.CollectionUtils;
 import com.uas.kanban.util.ObjectUtils;
 import org.mongodb.morphia.annotations.*;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -199,7 +200,7 @@ public class PanelInstance extends BaseEntity {
     /**
      * 看板 code 及启用状态
      */
-    public static class RelatedKanban {
+    public static class RelatedKanban implements Serializable {
 
         /**
          * 看板 code {@link Kanban}

+ 115 - 27
kanban-console/src/main/java/com/uas/kanban/service/impl/PanelInstanceServiceImpl.java

@@ -26,7 +26,6 @@ import org.springframework.stereotype.Service;
 
 import javax.xml.transform.TransformerException;
 import java.io.IOException;
-import java.io.NotSerializableException;
 import java.sql.SQLException;
 import java.util.*;
 
@@ -61,19 +60,30 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
 
     @Override
     public int update(@NotEmpty("json") String json) throws IllegalArgumentException, OperationException {
+        JSONObject jsonObject = JSONObject.parseObject(json);
+        checkRelatedFields(jsonObject);
+        // 处理参数后,要将参数写回
         PanelInstance panelInstance = panelInstanceDao.parse(json);
-        checkParameters(panelInstance);
+        panelInstance.toParameters(processParameters(panelInstance));
         return panelInstanceDao.update(panelInstance);
     }
 
     @Override
     public int updatePart(@NotEmpty("json") String json) throws IllegalArgumentException, OperationException {
-        return update(json);
+        JSONObject jsonObject = JSONObject.parseObject(json);
+        checkRelatedFields(jsonObject);
+        // 处理参数后,要将参数写回到 json 中
+        List<Parameter> parameters = processParameters(panelInstanceDao.parse(json));
+        if (parameters != null) {
+            jsonObject.put("parameters", JSONObject.toJSONString(parameters));
+        }
+        return super.updatePart(jsonObject.toJSONString());
     }
 
     @Override
     public Map<String, Object> parseData(@NotEmpty("code") String code, String kanbanCode) {
         PanelInstance panelInstance = panelInstanceDao.checkExist(code);
+        BaseDao.checkFields(panelInstance);
         Panel panel = panelDao.checkExist(panelInstance.getPanelCode());
         List<PanelInstance.RelatedKanban> relatedKanbans = panelInstance.getRelatedKanbans();
         if (CollectionUtils.isEmpty(relatedKanbans)) {
@@ -154,26 +164,103 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
     }
 
     /**
-     * 检查参数是否正确填写(没有遗漏参数、每个参数都有值并且类型匹配)
+     * 检查关联的字段是否被修改,包括 panelCode, userCode, relatedKanbans 等
      *
-     * @param panelInstance 面板实例
+     * @param jsonObject 面板实例
+     * @throws OperationException panelCode, userCode 等被修改
      */
-    private void checkParameters(@NotEmpty("panelInstance") PanelInstance panelInstance) {
-        List<Parameter> parameters = panelInstance.fromParameters();
+    private void checkRelatedFields(@NotEmpty("jsonObject") JSONObject jsonObject) throws OperationException {
+        String code = jsonObject.getString("code");
+        if (StringUtils.isEmpty(code)) {
+            throw new IllegalArgumentException("未指定 code");
+        }
+
+        PanelInstance panelInstance = panelInstanceDao.checkExist(code);
+        // 检查关联的面板、用户 code 等信息
+        compareWithOldValue(jsonObject.getString("panelCode"), panelInstance.getPanelCode(), "panelCode");
+        compareWithOldValue(jsonObject.getString("userCode"), panelInstance.getPanelCode(), "userCode");
+        compareWithOldValue(jsonObject.getLong("panelVersion"), panelInstance.getPanelVersion(), "panelVersion");
+        // 检查关联的看板
+        List<PanelInstance.RelatedKanban> relatedKanbans = ObjectUtils.toList(jsonObject.getJSONArray("relatedKanbans"), PanelInstance.RelatedKanban.class);
+        checkRelatedKanbans(relatedKanbans, panelInstance.getRelatedKanbans());
+    }
+
+    /**
+     * 检查旧值
+     *
+     * @param value    新值
+     * @param oldValue 旧值
+     * @param field    检查的字段
+     * @throws OperationException 新旧值不同
+     */
+    private void compareWithOldValue(Object value, Object oldValue, @NotEmpty("field") String field) throws OperationException {
+        if (value != null && !value.equals(oldValue)) {
+            throw new OperationException("不可修改 " + field);
+        }
+    }
+
+    /**
+     * 检查关联的看板信息
+     *
+     * @param relatedKanbans    新值
+     * @param oldRelatedKanbans 旧值
+     */
+    private void checkRelatedKanbans(List<PanelInstance.RelatedKanban> relatedKanbans, List<PanelInstance.RelatedKanban> oldRelatedKanbans) {
+        // 因为对象会被修改,所以先进行深克隆
+        List<PanelInstance.RelatedKanban> relatedKanbansClone;
         try {
-            if (!CollectionUtils.isEmpty(parameters)) {
-                for (Parameter parameter : parameters) {
-                    parameter.mayInitValue();
+            relatedKanbansClone = (List<PanelInstance.RelatedKanban>) ObjectUtils.clone(relatedKanbans);
+        } catch (Throwable e) {
+            throw new IllegalStateException("深克隆对象时失败", e);
+        }
+        if (relatedKanbansClone == null) {
+            return;
+        }
+        for (int i = relatedKanbansClone.size() - 1; i >= 0; i--) {
+            PanelInstance.RelatedKanban relatedKanban = relatedKanbansClone.get(i);
+            for (int j = oldRelatedKanbans == null ? -1 : relatedKanbansClone.size() - 1; j >= 0; j--) {
+                PanelInstance.RelatedKanban oldRelatedKanban = oldRelatedKanbans.get(j);
+                if (Objects.equals(relatedKanban.getCode(), oldRelatedKanban.getCode())) {
+                    if (!Objects.equals(relatedKanban.getName(), oldRelatedKanban.getName())) {
+                        throw new IllegalArgumentException("不可修改关联看板名称:" + relatedKanban);
+                    }
+                    // 移除通过检查的参数
+                    relatedKanbansClone.remove(i);
+                    oldRelatedKanbans.remove(j);
                 }
             }
-            List<Parameter> references = generateParameters(panelInstance.getPanelCode());
-            // 重置 SQL 类型的参数(其值是解析出来的,不进行保存)
-            resetSQLParameter(parameters, references);
-            panelInstance.toParameters(parameters);
-            compare(parameters, references);
-        } catch (ClassNotFoundException | IOException | InstantiationException | IllegalAccessException e) {
-            throw new IllegalStateException("深克隆对象时失败", e);
         }
+        if (!CollectionUtils.isEmpty(relatedKanbansClone)) {
+            throw new IllegalArgumentException("不可新增关联看板信息:" + relatedKanbansClone);
+        }
+        if (!CollectionUtils.isEmpty(oldRelatedKanbans)) {
+            throw new IllegalArgumentException("不可删除关联看板信息:" + oldRelatedKanbans);
+        }
+    }
+
+
+    /**
+     * 处理参数,包括检查参数是否正确填写(没有遗漏参数、每个参数都有值并且类型匹配)、重置 SQL 类型参数等
+     *
+     * @param panelInstance 面板实例
+     * @return 处理后的参数(可能重置了 SQL 类型参数)
+     */
+    private List<Parameter> processParameters(@NotEmpty("panelInstance") PanelInstance panelInstance) {
+        List<Parameter> parameters = panelInstance.fromParameters();
+        if (!CollectionUtils.isEmpty(parameters)) {
+            for (Parameter parameter : parameters) {
+                parameter.mayInitValue();
+            }
+        }
+        String panelCode = panelInstance.getPanelCode();
+        if (panelCode == null) {
+            panelCode = panelInstanceDao.checkExist(panelInstance.codeNotEmpty()).getPanelCode();
+        }
+        List<Parameter> references = generateParameters(panelCode);
+        // 重置 SQL 类型的参数(其值是根据 SQL 解析出来的,不能保存到 optionValues)
+        resetSQLParameter(parameters, references);
+        compare(parameters, references);
+        return parameters;
     }
 
     /**
@@ -200,8 +287,7 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
      * @param references 参照对象
      */
     private void resetSQLParameter(List<Parameter> parameters, List<Parameter> references) {
-        int parametersSize = parameters == null ? -1 : parameters.size() - 1;
-        for (int i = parametersSize; i >= 0; i--) {
+        for (int i = parameters == null ? -1 : parameters.size() - 1; i >= 0; i--) {
             Parameter parameter = parameters.get(i);
             // 只重置 SQL 类型
             if (parameter.getType() != Type.SQL) {
@@ -223,13 +309,15 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
      * @param parameters 比较的对象
      * @param references 参照对象
      */
-    private void compare(List<Parameter> parameters, List<Parameter> references)
-            throws NotSerializableException, InstantiationException, IllegalAccessException, ClassNotFoundException,
-            IOException {
+    private void compare(List<Parameter> parameters, List<Parameter> references) {
         // 因为对象会被修改,所以先进行深克隆,参照对象不需要克隆
-        List<Parameter> parametersClone = (List<Parameter>) ObjectUtils.clone(parameters);
-        int parametersSize = parametersClone == null ? -1 : parametersClone.size() - 1;
-        for (int i = parametersSize; i >= 0; i--) {
+        List<Parameter> parametersClone;
+        try {
+            parametersClone = (List<Parameter>) ObjectUtils.clone(parameters);
+        } catch (Throwable e) {
+            throw new IllegalStateException("深克隆对象时失败", e);
+        }
+        for (int i = parametersClone == null ? -1 : parametersClone.size() - 1; i >= 0; i--) {
             Parameter parameter = parametersClone.get(i);
             // 先检查值
             parameter.checkValue();
@@ -244,8 +332,8 @@ public class PanelInstanceServiceImpl extends BaseService<PanelInstance> impleme
                         throw new IllegalArgumentException("参数属性不一致:" + parameter + ",应为:" + reference);
                     }
                     // 移除比较对象中通过检查的参数,最终剩下的全是不合法的参数
-                    parametersClone.remove(parameter);
-                    references.remove(reference);
+                    parametersClone.remove(i);
+                    references.remove(j);
                 }
             }
         }