是否有适当的模式或方法来遍历数据并动态构建对象?

时间:2018-02-21 16:55:43

标签: java design-patterns jaxb

我正在寻找一些关于对象遍历的设计模式建议,以根据所呈现的数据动态构建对象。

下面,我手动构建此对象。最初,根节点是BinaryLogicOpType,但可能是基于rootNodeType的不同对象。

我的问题是..我需要根据列表中的字符串数据动态构造不同类型的这些对象。这样做的最佳途径是什么?

如果这些问题令人困惑,我愿意改进这些问题。

String rootNodeType = fN.type;

BinaryLogicOpType _blop = new BinaryLogicOpType();
JAXBElement<BinaryLogicOpType> root = constructRootElement(_blop, factory, rootNodeType);

/** LETS CREATE THE FIRST CHILD ELEMENT */
BinaryComparisonOpType attrName1GTEFive = new BinaryComparisonOpType();
_blop.getOps().add(factory.createPropertyIsEqualTo(attrName1GTEFive));

JAXBElement<String> attr1Property = factory.createValueReference(fN.nodes.get(0).getProperty());
LiteralType attr1ValueLiteral = new LiteralType();
attr1ValueLiteral.getContent().add(fN.nodes.get(0).getValue());

JAXBElement<LiteralType> attr1Value = factory.createLiteral(attr1ValueLiteral);

attrName1GTEFive.getExpression().add(attr1Property);
attrName1GTEFive.getExpression().add(attr1Value);

示例JSON

{
  "type": "AND",
  "filters": [
    {
      "type": "=",
      "value": "exampleid",
      "property": "id"
    },
    {
      "type": "ILIKE",
      "value": "*",
      "property": "metacard-tags"
    },
    {
      "type": "OR",
      "filters": [
        {
          "type": ">=",
          "value": null,
          "property": "benumber"
        },
        {
          "type": "ILIKE",
          "value": "redshirts",
          "property": "title",
          "isCaseSensitive": true
        }
      ]
    }
  ]
}

示例XML

<?xml version="1.0" encoding="UTF-8"?><fes:Filter xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:gml="http://www.opengis.net/gml/3.2">
  <fes:Or>
    <fes:PropertyIsLessThan matchAction="ANY" matchCase="false">
      <fes:ValueReference>name</fes:ValueReference>
      <fes:Function name="sub">
        <fes:Literal>my-id</fes:Literal>
      </fes:Function>
    </fes:PropertyIsLessThan>
    <fes:And>
      <fes:PropertyIsGreaterThanOrEqualTo matchAction="ANY" matchCase="false">
        <fes:ValueReference>attName</fes:ValueReference>
        <fes:Literal>5</fes:Literal>
      </fes:PropertyIsGreaterThanOrEqualTo>
      <fes:PropertyIsLike escapeChar="\" matchCase="false" singleChar="?" wildCard="*">
        <fes:ValueReference>title</fes:ValueReference>
        <fes:Literal>greetings</fes:Literal>
      </fes:PropertyIsLike>
      <fes:PropertyIsEqual>
        <fes:ValueReference>be_number</fes:ValueReference>
        <fes:Function>
            <fes:Parameter>null</fes:Parameter>
            <fes:Parameter>null</fes:Parameter>
        </fes:Function> 
      </fes:PropertyIsEqual>
    </fes:And>
  </fes:Or>
</fes:Filter>

1 个答案:

答案 0 :(得分:0)

我认为实际上没有简单的解决方案,但我确信可以通过OOP以非常优雅的方式实现转换。

基本上,在这两种情况下,你都在处理AST。它们的结构完全不同。因此,如果您设法为每种可能的节点类型实现转换例程,您应该能够转换整个AST。

首先,我首先为您的JSON结构实现一个好的Java模型。类似AndExpressionComparisonExpressionLikeExpressionOrExpression等类。有关灵感,请检查Filter架构的生成类。良好的建模在这里至关重要。

使用poliformic反序列化,以便在解析Jackson之后获得正确的对象结构。现在你“只”需要将这个结构转换为你的JAXB结构。

最简单的方法是直接将转换方法添加到JSON模型类中。我会让它们都实现一个方法,如:

public Object convertToJAXB(ObjectFactory objectFactory);

对于像ILIKE这样的“叶子”AST节点,你可以直接构造适当的对象 对于像ANDOR这样的“复合”AST节点,您需要在每个convertToJAXB上调用filters,然后通过将结果包装到其中来完成更多工作JAXBElements。您可能需要在此处进行一些instanceof检查;应该可以提出更智能的解决方案。