• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / ibatis-2 / 573

26 May 2025 06:21PM UTC coverage: 65.532%. Remained the same
573

push

github

web-flow
Merge pull request #284 from hazendaz/master

[java] Use diamond operators

1611 of 2820 branches covered (57.13%)

61 of 72 new or added lines in 37 files covered. (84.72%)

5082 of 7755 relevant lines covered (65.53%)

0.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.02
/src/main/java/com/ibatis/common/beans/DomProbe.java
1
/*
2
 * Copyright 2004-2025 the original author or authors.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *    https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.ibatis.common.beans;
17

18
import com.ibatis.common.resources.Resources;
19

20
import java.io.PrintWriter;
21
import java.io.StringWriter;
22
import java.util.ArrayList;
23
import java.util.Collection;
24
import java.util.Iterator;
25
import java.util.List;
26
import java.util.StringTokenizer;
27

28
import org.w3c.dom.CharacterData;
29
import org.w3c.dom.Document;
30
import org.w3c.dom.Element;
31
import org.w3c.dom.NamedNodeMap;
32
import org.w3c.dom.Node;
33
import org.w3c.dom.NodeList;
34
import org.w3c.dom.Text;
35

36
/**
37
 * A Probe implementation for working with DOM objects.
38
 */
39
public class DomProbe extends BaseProbe {
1✔
40

41
  @Override
42
  public String[] getReadablePropertyNames(Object object) {
NEW
43
    List props = new ArrayList<>();
×
44
    Element e = resolveElement(object);
×
45
    NodeList nodes = e.getChildNodes();
×
46
    for (int i = 0; i < nodes.getLength(); i++) {
×
47
      props.add(nodes.item(i).getNodeName());
×
48
    }
49
    return (String[]) props.toArray(new String[props.size()]);
×
50
  }
51

52
  @Override
53
  public String[] getWriteablePropertyNames(Object object) {
NEW
54
    List props = new ArrayList<>();
×
55
    Element e = resolveElement(object);
×
56
    NodeList nodes = e.getChildNodes();
×
57
    for (int i = 0; i < nodes.getLength(); i++) {
×
58
      props.add(nodes.item(i).getNodeName());
×
59
    }
60
    return (String[]) props.toArray(new String[props.size()]);
×
61
  }
62

63
  public Class getPropertyTypeForSetter(Object object, String name) {
64
    Element e = findNestedNodeByName(resolveElement(object), name, false);
×
65
    // todo alias types, don't use exceptions like this
66
    try {
67
      return Resources.classForName(e.getAttribute("type"));
×
68
    } catch (ClassNotFoundException e1) {
×
69
      return Object.class;
×
70
    }
71
  }
72

73
  public Class getPropertyTypeForGetter(Object object, String name) {
74
    Element e = findNestedNodeByName(resolveElement(object), name, false);
×
75
    // todo alias types, don't use exceptions like this
76
    try {
77
      return Resources.classForName(e.getAttribute("type"));
×
78
    } catch (ClassNotFoundException e1) {
×
79
      return Object.class;
×
80
    }
81
  }
82

83
  public boolean hasWritableProperty(Object object, String propertyName) {
84
    return findNestedNodeByName(resolveElement(object), propertyName, false) != null;
×
85
  }
86

87
  public boolean hasReadableProperty(Object object, String propertyName) {
88
    return findNestedNodeByName(resolveElement(object), propertyName, false) != null;
×
89
  }
90

91
  public Object getObject(Object object, String name) {
92
    Object value = null;
1✔
93
    Element element = findNestedNodeByName(resolveElement(object), name, false);
1✔
94
    if (element != null) {
1!
95
      value = getElementValue(element);
1✔
96
    }
97
    return value;
1✔
98
  }
99

100
  public void setObject(Object object, String name, Object value) {
101
    Element element = findNestedNodeByName(resolveElement(object), name, true);
1✔
102
    if (element != null) {
1!
103
      setElementValue(element, value);
1✔
104
    }
105
  }
1✔
106

107
  @Override
108
  protected void setProperty(Object object, String property, Object value) {
109
    Element element = findNodeByName(resolveElement(object), property, 0, true);
×
110
    if (element != null) {
×
111
      setElementValue(element, value);
×
112
    }
113
  }
×
114

115
  @Override
116
  protected Object getProperty(Object object, String property) {
117
    Object value = null;
×
118
    Element element = findNodeByName(resolveElement(object), property, 0, false);
×
119
    if (element != null) {
×
120
      value = getElementValue(element);
×
121
    }
122
    return value;
×
123
  }
124

125
  /**
126
   * Resolve element.
127
   *
128
   * @param object
129
   *          the object
130
   *
131
   * @return the element
132
   */
133
  private Element resolveElement(Object object) {
134
    Element element = null;
1✔
135
    if (object instanceof Document) {
1!
136
      element = (Element) ((Document) object).getLastChild();
1✔
137
    } else if (object instanceof Element) {
×
138
      element = (Element) object;
×
139
    } else {
140
      throw new ProbeException("An unknown object type was passed to DomProbe.  Must be a Document.");
×
141
    }
142
    return element;
1✔
143
  }
144

145
  /**
146
   * Sets the element value.
147
   *
148
   * @param element
149
   *          the element
150
   * @param value
151
   *          the value
152
   */
153
  private void setElementValue(Element element, Object value) {
154
    CharacterData data = null;
1✔
155

156
    Element prop = element;
1✔
157

158
    if (value instanceof Collection) {
1✔
159
      Iterator items = ((Collection) value).iterator();
1✔
160
      while (items.hasNext()) {
1✔
161
        Document valdoc = (Document) items.next();
1✔
162
        NodeList list = valdoc.getChildNodes();
1✔
163
        for (int i = 0; i < list.getLength(); i++) {
1✔
164
          Node newNode = element.getOwnerDocument().importNode(list.item(i), true);
1✔
165
          element.appendChild(newNode);
1✔
166
        }
167
      }
1✔
168
    } else if (value instanceof Document) {
1✔
169
      Document valdoc = (Document) value;
1✔
170
      Node lastChild = valdoc.getLastChild();
1✔
171
      NodeList list = lastChild.getChildNodes();
1✔
172
      for (int i = 0; i < list.getLength(); i++) {
1✔
173
        Node newNode = element.getOwnerDocument().importNode(list.item(i), true);
1✔
174
        element.appendChild(newNode);
1✔
175
      }
176
    } else if (value instanceof Element) {
1!
177
      Node newNode = element.getOwnerDocument().importNode((Element) value, true);
×
178
      element.appendChild(newNode);
×
179
    } else {
×
180
      // Find text child element
181
      NodeList texts = prop.getChildNodes();
1✔
182
      if (texts.getLength() == 1) {
1!
183
        Node child = texts.item(0);
×
184
        if (child instanceof CharacterData) {
×
185
          // Use existing text.
186
          data = (CharacterData) child;
×
187
        } else {
188
          // Remove non-text, add text.
189
          prop.removeChild(child);
×
190
          Text text = prop.getOwnerDocument().createTextNode(String.valueOf(value));
×
191
          prop.appendChild(text);
×
192
          data = text;
×
193
        }
194
      } else if (texts.getLength() > 1) {
1!
195
        // Remove all, add text.
196
        for (int i = texts.getLength() - 1; i >= 0; i--) {
×
197
          prop.removeChild(texts.item(i));
×
198
        }
199
        Text text = prop.getOwnerDocument().createTextNode(String.valueOf(value));
×
200
        prop.appendChild(text);
×
201
        data = text;
×
202
      } else {
×
203
        // Add text.
204
        Text text = prop.getOwnerDocument().createTextNode(String.valueOf(value));
1✔
205
        prop.appendChild(text);
1✔
206
        data = text;
1✔
207
      }
208
      data.setData(String.valueOf(value));
1✔
209
    }
210

211
    // Set type attribute
212
    // prop.setAttribute("type", value == null ? "null" : value.getClass().getName());
213

214
  }
1✔
215

216
  /**
217
   * Gets the element value.
218
   *
219
   * @param element
220
   *          the element
221
   *
222
   * @return the element value
223
   */
224
  private Object getElementValue(Element element) {
225
    StringBuilder value = null;
1✔
226

227
    Element prop = element;
1✔
228

229
    if (prop != null) {
1!
230
      // Find text child elements
231
      NodeList texts = prop.getChildNodes();
1✔
232
      if (texts.getLength() > 0) {
1!
233
        value = new StringBuilder();
1✔
234
        for (int i = 0; i < texts.getLength(); i++) {
1✔
235
          Node text = texts.item(i);
1✔
236
          if (text instanceof CharacterData) {
1!
237
            value.append(((CharacterData) text).getData());
1✔
238
          }
239
        }
240
      }
241
    }
242

243
    // convert to proper type
244
    // value = convert(value.toString());
245

246
    if (value == null) {
1!
247
      return null;
×
248
    } else {
249
      return value.toString();
1✔
250
    }
251
  }
252

253
  /**
254
   * Find nested node by name.
255
   *
256
   * @param element
257
   *          the element
258
   * @param name
259
   *          the name
260
   * @param create
261
   *          the create
262
   *
263
   * @return the element
264
   */
265
  private Element findNestedNodeByName(Element element, String name, boolean create) {
266
    Element child = element;
1✔
267

268
    StringTokenizer parser = new StringTokenizer(name, ".", false);
1✔
269
    while (parser.hasMoreTokens()) {
1✔
270
      String childName = parser.nextToken();
1✔
271
      if (childName.indexOf('[') > -1) {
1✔
272
        String propName = childName.substring(0, childName.indexOf('['));
1✔
273
        int i = Integer.parseInt(childName.substring(childName.indexOf('[') + 1, childName.indexOf(']')));
1✔
274
        child = findNodeByName(child, propName, i, create);
1✔
275
      } else {
1✔
276
        child = findNodeByName(child, childName, 0, create);
1✔
277
      }
278
      if (child == null) {
1!
279
        break;
×
280
      }
281
    }
1✔
282

283
    return child;
1✔
284
  }
285

286
  /**
287
   * Find node by name.
288
   *
289
   * @param element
290
   *          the element
291
   * @param name
292
   *          the name
293
   * @param index
294
   *          the index
295
   * @param create
296
   *          the create
297
   *
298
   * @return the element
299
   */
300
  private Element findNodeByName(Element element, String name, int index, boolean create) {
301
    Element prop = null;
1✔
302

303
    // Find named property element
304
    NodeList propNodes = element.getElementsByTagName(name);
1✔
305
    if (propNodes.getLength() > index) {
1✔
306
      prop = (Element) propNodes.item(index);
1✔
307
    } else {
308
      if (create) {
1!
309
        for (int i = 0; i < index + 1; i++) {
1✔
310
          prop = element.getOwnerDocument().createElement(name);
1✔
311
          element.appendChild(prop);
1✔
312
        }
313
      }
314
    }
315
    return prop;
1✔
316
  }
317

318
  /**
319
   * Converts a DOM node to a complete xml string.
320
   *
321
   * @param node
322
   *          - the node to process
323
   * @param indent
324
   *          - how to indent the children of the node
325
   *
326
   * @return The node as a String
327
   */
328
  public static String nodeToString(Node node, String indent) {
329
    StringWriter stringWriter = new StringWriter();
×
330
    PrintWriter printWriter = new PrintWriter(stringWriter);
×
331

332
    switch (node.getNodeType()) {
×
333

334
      case Node.DOCUMENT_NODE:
335
        printWriter.println("<xml version=\"1.0\">\n");
×
336
        // recurse on each child
337
        NodeList nodes = node.getChildNodes();
×
338
        if (nodes != null) {
×
339
          for (int i = 0; i < nodes.getLength(); i++) {
×
340
            printWriter.print(nodeToString(nodes.item(i), ""));
×
341
          }
342
        }
343
        break;
344

345
      case Node.ELEMENT_NODE:
346
        String name = node.getNodeName();
×
347
        printWriter.print(indent + "<" + name);
×
348
        NamedNodeMap attributes = node.getAttributes();
×
349
        for (int i = 0; i < attributes.getLength(); i++) {
×
350
          Node current = attributes.item(i);
×
351
          printWriter.print(" " + current.getNodeName() + "=\"" + current.getNodeValue() + "\"");
×
352
        }
353
        printWriter.print(">");
×
354

355
        // recurse on each child
356
        NodeList children = node.getChildNodes();
×
357
        if (children != null) {
×
358
          for (int i = 0; i < children.getLength(); i++) {
×
359
            printWriter.print(nodeToString(children.item(i), indent + indent));
×
360
          }
361
        }
362

363
        printWriter.print("</" + name + ">");
×
364
        break;
×
365

366
      case Node.TEXT_NODE:
367
        printWriter.print(node.getNodeValue());
×
368
        break;
369
    }
370

371
    printWriter.flush();
×
372
    String result = stringWriter.getBuffer().toString();
×
373
    printWriter.close();
×
374

375
    return result;
×
376
  }
377

378
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc