1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.frontend.xeditor;
20
21 import java.util.List;
22
23 import org.jaxen.BaseXPath;
24 import org.jaxen.JaxenException;
25 import org.jaxen.dom.DocumentNavigator;
26 import org.jaxen.expr.Expr;
27 import org.jaxen.expr.LocationPath;
28 import org.jaxen.expr.Step;
29 import org.jdom2.Element;
30 import org.jdom2.JDOMException;
31 import org.mycore.common.config.MCRConfiguration2;
32 import org.mycore.common.xml.MCRNodeBuilder;
33 import org.mycore.frontend.xeditor.tracker.MCRAddedElement;
34 import org.mycore.frontend.xeditor.tracker.MCRSwapElements;
35
36 public class MCRRepeatBinding extends MCRBinding {
37
38 private int repeatPosition;
39
40 private int maxRepeats;
41
42 private static final String DEFAULT_METHOD = MCRConfiguration2.getString("MCR.XEditor.InsertTarget.DefaultMethod")
43 .orElse("build");
44
45 private String method = DEFAULT_METHOD;
46
47 public MCRRepeatBinding(String xPath, MCRBinding parent, int minRepeats, int maxRepeats, String method)
48 throws JaxenException,
49 JDOMException {
50 this(xPath, parent, method);
51
52 while (getBoundNodes().size() < minRepeats) {
53 insert(getBoundNodes().size());
54 }
55
56 this.maxRepeats = maxRepeats < 1 ? Integer.MAX_VALUE : maxRepeats;
57 this.maxRepeats = Math.max(this.maxRepeats, getBoundNodes().size());
58 }
59
60 public MCRRepeatBinding(String xPath, MCRBinding parent, String method) throws JaxenException, JDOMException {
61 super(xPath, true, parent);
62 this.method = "clone".equals(method) ? "clone" : "build".equals(method) ? "build" : DEFAULT_METHOD;
63 this.maxRepeats = Integer.MAX_VALUE;
64 }
65
66 public int getRepeatPosition() {
67 return repeatPosition;
68 }
69
70 public MCRBinding bindRepeatPosition() throws JDOMException, JaxenException {
71 repeatPosition++;
72 return new MCRBinding(repeatPosition, this);
73 }
74
75 public int getMaxRepeats() {
76 return maxRepeats;
77 }
78
79 public String getMethod() {
80 return method;
81 }
82
83 public Element getParentElement() {
84 return ((Element) getBoundNode()).getParentElement();
85 }
86
87 @SuppressWarnings("unchecked")
88 public String getElementNameWithPredicates() throws JaxenException {
89 BaseXPath baseXPath = new BaseXPath(xPath, new DocumentNavigator());
90 Expr rootExpr = baseXPath.getRootExpr();
91 LocationPath locationPath = (LocationPath) rootExpr;
92 List<Step> steps = locationPath.getSteps();
93 Step lastStep = steps.get(steps.size() - 1);
94 return MCRNodeBuilder.simplify(lastStep.getText());
95 }
96
97 public void swap(int pos) {
98 Element parent = getParentElement();
99 Element elementA = (Element) (getBoundNodes().get(pos - 1));
100 Element elementB = (Element) (getBoundNodes().get(pos));
101 track(MCRSwapElements.swap(parent, elementA, elementB));
102 }
103
104 public void insert(int pos) throws JaxenException {
105 if ("build".equals(method)) {
106 Element parentElement = getParentElement();
107 Element precedingElement = (Element) (getBoundNodes().get(pos - 1));
108 int posOfPrecedingInParent = parentElement.indexOf(precedingElement);
109 int targetPos = posOfPrecedingInParent + 1;
110 String pathToBuild = getElementNameWithPredicates();
111 Element newElement = (Element) (new MCRNodeBuilder().buildNode(pathToBuild, null, null));
112 parentElement.addContent(targetPos, newElement);
113 boundNodes.add(pos, newElement);
114 track(MCRAddedElement.added(newElement));
115 } else {
116 cloneBoundElement(pos - 1);
117 }
118 }
119 }