Révision 2597
tmp/org.txm.core/src/java/org/txm/xml/ToDoListHookActivator.java (revision 2597) | ||
---|---|---|
1 |
package org.txm.xml; |
|
2 |
|
|
3 |
import java.io.IOException; |
|
4 |
import java.util.List; |
|
5 |
|
|
6 |
import javax.xml.stream.XMLStreamException; |
|
7 |
|
|
8 |
/** |
|
9 |
* To use if you have N elements to process with a specific localname for each one |
|
10 |
* |
|
11 |
* @author mdecorde |
|
12 |
* |
|
13 |
*/ |
|
14 |
public class ToDoListHookActivator extends HookActivator { |
|
15 |
|
|
16 |
List<String> tasks; |
|
17 |
|
|
18 |
int current = 0; |
|
19 |
|
|
20 |
public ToDoListHookActivator(List<String> tasks) throws IOException, XMLStreamException { |
|
21 |
this.tasks = tasks; |
|
22 |
} |
|
23 |
|
|
24 |
@Override |
|
25 |
public boolean mustActivate() { |
|
26 |
if (tasks.size() <= current) return false; |
|
27 |
|
|
28 |
return tasks.get(current).equals(hook.getLocalName()); |
|
29 |
} |
|
30 |
|
|
31 |
@Override |
|
32 |
public void hookWasActivated() { |
|
33 |
current++; |
|
34 |
} |
|
35 |
} |
tmp/org.txm.core/src/java/org/txm/xml/DOMIdentityHook.java (revision 2597) | ||
---|---|---|
1 |
package org.txm.xml; |
|
2 |
|
|
3 |
import java.io.IOException; |
|
4 |
|
|
5 |
import javax.xml.stream.XMLStreamException; |
|
6 |
|
|
7 |
import org.txm.utils.xml.DomUtils; |
|
8 |
import org.w3c.dom.Element; |
|
9 |
import org.w3c.dom.Node; |
|
10 |
import org.w3c.dom.NodeList; |
|
11 |
|
|
12 |
public class DOMIdentityHook extends Hook { |
|
13 |
|
|
14 |
Element dom; |
|
15 |
|
|
16 |
public DOMIdentityHook(String name, HookActivator activator, XMLProcessor processor) throws IOException, XMLStreamException { |
|
17 |
super(name, activator, processor); |
|
18 |
} |
|
19 |
|
|
20 |
@Override |
|
21 |
public boolean _activate() { |
|
22 |
StaxDomConstructor domConstructor = new StaxDomConstructor(parentParser.parser); |
|
23 |
try { |
|
24 |
dom = domConstructor.getDom(); |
|
25 |
return dom != null; |
|
26 |
} catch (Exception e) { |
|
27 |
// TODO Auto-generated catch block |
|
28 |
e.printStackTrace(); |
|
29 |
return false; |
|
30 |
} |
|
31 |
} |
|
32 |
|
|
33 |
@Override |
|
34 |
public boolean mustDeactivate() { |
|
35 |
boolean b = dom != null; // the DOM has been constructed and the XMLProcess can continue parsing |
|
36 |
if (b) { |
|
37 |
try { |
|
38 |
writeDOM(); |
|
39 |
dom = null; |
|
40 |
} catch (XMLStreamException e) { |
|
41 |
e.printStackTrace(); |
|
42 |
} |
|
43 |
} |
|
44 |
return b; |
|
45 |
} |
|
46 |
|
|
47 |
@Override |
|
48 |
public boolean deactivate() { |
|
49 |
return dom == null; // dom should be null |
|
50 |
} |
|
51 |
|
|
52 |
private void writeDOM() throws XMLStreamException { |
|
53 |
writeDOM(dom); |
|
54 |
} |
|
55 |
|
|
56 |
private void writeDOM(Node node) throws XMLStreamException { |
|
57 |
if (node.getNodeType() == Node.ELEMENT_NODE) { |
|
58 |
Element e = (Element)node; |
|
59 |
NodeList children = e.getChildNodes(); |
|
60 |
if (children.getLength() > 0) { |
|
61 |
parentParser.writer.writeStartElement(e.getNamespaceURI(), e.getLocalName()); |
|
62 |
} else { |
|
63 |
parentParser.writer.writeEmptyElement(e.getNamespaceURI(),e.getLocalName()); |
|
64 |
} |
|
65 |
|
|
66 |
for (int i = 0 ; i < e.getAttributes().getLength() ; i++) { |
|
67 |
Node att = e.getAttributes().item(i); |
|
68 |
parentParser.writer.writeAttribute(att.getNamespaceURI(), att.getNodeName(), att.getNodeValue()); |
|
69 |
} |
|
70 |
|
|
71 |
for (int c = 0 ; c < children.getLength() ; c++) { |
|
72 |
writeDOM(children.item(c)); |
|
73 |
} |
|
74 |
if (children.getLength() > 0) { |
|
75 |
parentParser.writer.writeEndElement(); |
|
76 |
} |
|
77 |
} else if (node.getNodeType() == Node.TEXT_NODE) { |
|
78 |
parentParser.writer.writeCharacters("T"+node.getTextContent()); |
|
79 |
} |
|
80 |
} |
|
81 |
|
|
82 |
@Override |
|
83 |
protected void processNamespace() throws XMLStreamException { } |
|
84 |
|
|
85 |
@Override |
|
86 |
protected void processStartElement() throws XMLStreamException, IOException { } |
|
87 |
|
|
88 |
@Override |
|
89 |
protected void processCharacters() throws XMLStreamException { } |
|
90 |
|
|
91 |
@Override |
|
92 |
protected void processProcessingInstruction() throws XMLStreamException { } |
|
93 |
|
|
94 |
@Override |
|
95 |
protected void processDTD() throws XMLStreamException { } |
|
96 |
|
|
97 |
@Override |
|
98 |
protected void processCDATA() throws XMLStreamException { } |
|
99 |
|
|
100 |
@Override |
|
101 |
protected void processComment() throws XMLStreamException { } |
|
102 |
|
|
103 |
@Override |
|
104 |
protected void processEndElement() throws XMLStreamException { } |
|
105 |
|
|
106 |
@Override |
|
107 |
protected void processEndDocument() throws XMLStreamException { } |
|
108 |
|
|
109 |
@Override |
|
110 |
protected void processEntityReference() throws XMLStreamException { } |
|
111 |
} |
|
0 | 112 |
tmp/org.txm.core/src/java/org/txm/xml/HookActivator.java (revision 2597) | ||
---|---|---|
28 | 28 |
/** |
29 | 29 |
* Use this method if you need the activator to be updated when the hook was activated once |
30 | 30 |
*/ |
31 |
public abstract void hookWasActivated();
|
|
31 |
protected abstract void hookWasActivated();
|
|
32 | 32 |
|
33 | 33 |
/** |
34 | 34 |
* Set afterward the hook |
tmp/org.txm.core/src/java/org/txm/xml/Hook.java (revision 2597) | ||
---|---|---|
49 | 49 |
*/ |
50 | 50 |
public final boolean activate() { |
51 | 51 |
elements = 0; |
52 |
if (activator != null) { |
|
53 |
activator.hookWasActivated(); |
|
54 |
} |
|
52 | 55 |
return _activate(); |
53 | 56 |
} |
54 | 57 |
|
... | ... | |
67 | 70 |
*/ |
68 | 71 |
public final boolean mustActivate() { |
69 | 72 |
if (activator == null) return false; |
73 |
|
|
70 | 74 |
return activator.mustActivate(); |
71 | 75 |
} |
72 | 76 |
|
73 |
public final boolean mustDeactivate() {
|
|
77 |
public boolean mustDeactivate() { |
|
74 | 78 |
return elements == 0; |
75 | 79 |
} |
76 | 80 |
|
tmp/org.txm.core/src/java/org/txm/xml/XMLProcessor.java (revision 2597) | ||
---|---|---|
6 | 6 |
import java.io.IOException; |
7 | 7 |
import java.io.InputStream; |
8 | 8 |
import java.net.URL; |
9 |
import java.util.Arrays; |
|
9 | 10 |
import java.util.HashMap; |
10 | 11 |
import java.util.LinkedHashMap; |
11 | 12 |
import java.util.Stack; |
... | ... | |
430 | 431 |
|
431 | 432 |
protected void processStartElement() throws XMLStreamException, IOException { |
432 | 433 |
String prefix = parser.getPrefix(); |
433 |
if (INCLUDE == localname && XI == prefix) { |
|
434 |
processXInclude(); |
|
435 |
} |
|
436 |
else { |
|
437 | 434 |
if (prefix != null && prefix.length() > 0) { |
438 | 435 |
writer.writeStartElement(Nscontext.getNamespaceURI(prefix), localname); |
439 | 436 |
} |
... | ... | |
446 | 443 |
} |
447 | 444 |
|
448 | 445 |
writeAttributes(); |
449 |
} |
|
450 | 446 |
} |
451 | 447 |
|
452 | 448 |
private void _processStartElement() throws XMLStreamException, IOException { |
453 | 449 |
String prefix = parser.getPrefix(); |
454 |
if (INCLUDE == localname && XI == prefix) { |
|
455 |
processXInclude(); |
|
456 |
} |
|
457 |
else { |
|
458 | 450 |
if (prefix != null && prefix.length() > 0) { |
459 | 451 |
writer.writeStartElement(Nscontext.getNamespaceURI(prefix), localname); |
460 | 452 |
} |
... | ... | |
466 | 458 |
} |
467 | 459 |
|
468 | 460 |
writeAttributes(); |
469 |
} |
|
470 | 461 |
} |
471 | 462 |
|
472 | 463 |
private Stack<LinkedHashMap<String, String>> attributesStack = new Stack<>(); |
... | ... | |
539 | 530 |
writer.writeEntityRef(parser.getLocalName()); |
540 | 531 |
} |
541 | 532 |
|
542 |
/** |
|
543 |
* Process the XInclude elements |
|
544 |
* |
|
545 |
* @throws IOException |
|
546 |
* @throws XMLStreamException |
|
547 |
*/ |
|
548 |
protected void processXInclude() throws XMLStreamException, IOException { |
|
549 |
String url = parser.getAttributeValue(null, "href"); // relative only |
|
550 |
File driver = new File(inputurl.getFile()); |
|
551 |
File ref = new File(driver.getParent(), url); |
|
552 |
if (ref.exists()) { |
|
553 |
URL includeurl = ref.toURI().toURL(); |
|
554 |
// save variables before killing them |
|
555 |
System.out.println("process xi include: " + ref); |
|
556 |
XMLStreamReader parserSave = this.parser; // back up current parser |
|
557 |
InputStream xiIncludeInputData = includeurl.openStream(); |
|
558 |
XMLStreamReader xiIncludeParser = factory.createXMLStreamReader(xiIncludeInputData); |
|
559 |
parser = xiIncludeParser; |
|
560 |
processingXInclude++; // to avoid recalling before & after methods |
|
561 |
this.process(writer); |
|
562 |
processingXInclude--; // end of XInclude processing |
|
563 |
this.parser = parserSave; // restore parser |
|
564 |
} |
|
565 |
else { |
|
566 |
System.out.println("Warning referenced file: $ref does not exists"); |
|
567 |
} |
|
568 |
} |
|
569 |
|
|
570 | 533 |
public String getCurrentPath() { |
571 | 534 |
return currentXPath.toString(); |
572 | 535 |
} |
... | ... | |
603 | 566 |
// parentParser.writer.writeAttribute("hook", name); |
604 | 567 |
// } |
605 | 568 |
// }; |
569 |
XPathHookActivator xpathActivator = new XPathHookActivator(null, "//p"); |
|
570 |
XPathsHookActivator xpathsActivator = new XPathsHookActivator(null, Arrays.asList("//p", "//p")); |
|
571 |
// IdentityHook hook2 = new IdentityHook("hook2", xpathsActivator, builder) { |
|
572 |
// |
|
573 |
// @Override |
|
574 |
// public boolean _activate() { |
|
575 |
// System.out.println("ACTIVATING " + name + " AT " + getLocation()); |
|
576 |
// return true; |
|
577 |
// } |
|
578 |
// |
|
579 |
// @Override |
|
580 |
// public boolean deactivate() { |
|
581 |
// System.out.println("DEACTIVATING " + name + " AT " + getLocation()); |
|
582 |
// return true; |
|
583 |
// } |
|
584 |
// |
|
585 |
// @Override |
|
586 |
// public void processStartElement() throws XMLStreamException, IOException { |
|
587 |
// super.processStartElement(); |
|
588 |
// parentParser.writer.writeAttribute("hook", name); |
|
589 |
// } |
|
590 |
// }; |
|
606 | 591 |
|
607 |
IdentityHook hook2 = new IdentityHook("hook2", new XPathHookActivator(null, "//language[@ident='fr']"), builder) { |
|
608 |
|
|
609 |
@Override |
|
610 |
public boolean _activate() { |
|
611 |
System.out.println("ACTIVATING " + name + " AT " + getLocation()); |
|
612 |
return true; |
|
613 |
} |
|
614 |
|
|
615 |
@Override |
|
616 |
public boolean deactivate() { |
|
617 |
System.out.println("DEACTIVATING " + name + " AT " + getLocation()); |
|
618 |
return true; |
|
619 |
} |
|
620 |
|
|
621 |
@Override |
|
622 |
public void processStartElement() throws XMLStreamException, IOException { |
|
623 |
super.processStartElement(); |
|
624 |
parentParser.writer.writeAttribute("hook", name); |
|
625 |
} |
|
592 |
DOMIdentityHook hook3 = new DOMIdentityHook("hook3", xpathsActivator, builder) { |
|
593 |
|
|
626 | 594 |
}; |
627 | 595 |
|
628 | 596 |
long time = System.currentTimeMillis(); |
629 | 597 |
if (builder.process(output)) { |
630 | 598 |
System.out.println("Time=" + (System.currentTimeMillis() - time)); |
599 |
System.out.println("XPaths activator has done working ? "+xpathsActivator.hasAllXpathsBeenProcessed()); |
|
631 | 600 |
} |
632 | 601 |
else { |
633 | 602 |
System.out.println("failure !"); |
tmp/org.txm.core/src/java/org/txm/xml/XPathHookActivator.java (revision 2597) | ||
---|---|---|
25 | 25 |
LinkedHashMap<String, String> attributesTest = null; |
26 | 26 |
|
27 | 27 |
|
28 |
private boolean debug = false;
|
|
28 |
protected boolean debug = false;
|
|
29 | 29 |
|
30 | 30 |
/** |
31 | 31 |
* @param localname the element localname to match |
... | ... | |
67 | 67 |
@Override |
68 | 68 |
public boolean mustActivate() { |
69 | 69 |
if (xpath == null) return false; |
70 |
if (p == null) return false; |
|
70 | 71 |
|
71 |
// System.out.println(hook.getCurrentPath() + hook.parentParser.getCurrentAttributes());
|
|
72 |
if (debug) System.out.println(hook.getCurrentPath() + hook.parentParser.getCurrentAttributes());
|
|
72 | 73 |
if (attributesTest != null) { |
73 |
return p.matcher(hook.getCurrentPath()).find() && hook.parentParser.getCurrentAttributes().equals(attributesTest);
|
|
74 |
return p.matcher(hook.getCurrentPath()).matches() && hook.parentParser.getCurrentAttributes().equals(attributesTest);
|
|
74 | 75 |
} |
75 | 76 |
else { |
76 |
return p.matcher(hook.getCurrentPath()).find();
|
|
77 |
return p.matcher(hook.getCurrentPath()).matches();
|
|
77 | 78 |
} |
78 | 79 |
} |
79 | 80 |
|
tmp/org.txm.core/src/java/org/txm/xml/XPathsHookActivator.java (revision 2597) | ||
---|---|---|
1 |
package org.txm.xml; |
|
2 |
|
|
3 |
import java.util.Arrays; |
|
4 |
import java.util.LinkedHashMap; |
|
5 |
import java.util.List; |
|
6 |
import java.util.regex.Pattern; |
|
7 |
import java.util.regex.PatternSyntaxException; |
|
8 |
|
|
9 |
import org.eclipse.osgi.util.NLS; |
|
10 |
import org.txm.utils.logger.Log; |
|
11 |
|
|
12 |
/** |
|
13 |
* Simple "XPath without attribute selector" Activator activated when the current path matches the xpath |
|
14 |
* |
|
15 |
* supported operators : / , // , * , node() |
|
16 |
* only the last element attributes can be tested with simple equals test |
|
17 |
* |
|
18 |
* exemple: //p[name='value'] |
|
19 |
* exemple: /text/node()/p[name='value'] |
|
20 |
* |
|
21 |
* @author mdecorde |
|
22 |
* |
|
23 |
*/ |
|
24 |
public class XPathsHookActivator extends XPathHookActivator { |
|
25 |
|
|
26 |
int currentXPath = 0; |
|
27 |
List<String> xpaths; |
|
28 |
|
|
29 |
/** |
|
30 |
* @param localname the element localname to match |
|
31 |
*/ |
|
32 |
public XPathsHookActivator(Hook hook, List<String> xpaths) { |
|
33 |
super(hook, xpaths.get(0)); |
|
34 |
this.xpaths = xpaths; |
|
35 |
|
|
36 |
loadNextXPath(); |
|
37 |
} |
|
38 |
|
|
39 |
/** |
|
40 |
* the xpaths used to build the patterns |
|
41 |
*/ |
|
42 |
public List<String> getXPaths() { |
|
43 |
return xpaths; |
|
44 |
} |
|
45 |
|
|
46 |
/** |
|
47 |
* |
|
48 |
*/ |
|
49 |
public int getCurrentXPathIndex() { |
|
50 |
return currentXPath; |
|
51 |
} |
|
52 |
|
|
53 |
/** |
|
54 |
* the xpaths used to build the patterns |
|
55 |
*/ |
|
56 |
public String getCurrentXPath() { |
|
57 |
if (xpaths.size() <= currentXPath) return null; |
|
58 |
|
|
59 |
return xpaths.get(currentXPath); |
|
60 |
} |
|
61 |
|
|
62 |
protected boolean loadNextXPath() { |
|
63 |
if (xpaths == null || xpaths.size() <= currentXPath) { |
|
64 |
p = null; |
|
65 |
return true; // nothing to load |
|
66 |
} |
|
67 |
|
|
68 |
String xpath = xpaths.get(currentXPath); |
|
69 |
String regex = xpath; |
|
70 |
|
|
71 |
int attrTest = xpath.indexOf("["); // [some tests] |
|
72 |
int lastNodeTest = xpath.lastIndexOf("/"); |
|
73 |
|
|
74 |
if (attrTest > 0 && attrTest > lastNodeTest) { |
|
75 |
attributesTest = new LinkedHashMap<>(); |
|
76 |
regex = xpath.substring(0, attrTest); |
|
77 |
String tail = xpath.substring(attrTest); |
|
78 |
tail = tail.substring(1, tail.length() - 1); |
|
79 |
if (debug) System.out.println("TAIL=" + tail); |
|
80 |
String tests[] = tail.split("@"); |
|
81 |
if (debug) System.out.println("TESTS=" + Arrays.toString(tests)); |
|
82 |
for (String test : tests) { |
|
83 |
if (test.length() == 0) continue; |
|
84 |
|
|
85 |
String split2[] = test.split("=", 2); // 0 name 1 "value" |
|
86 |
if (debug) System.out.println("TEST=" + Arrays.toString(split2)); |
|
87 |
attributesTest.put(split2[0], split2[1].substring(1, split2[1].length() - 1)); |
|
88 |
} |
|
89 |
} |
|
90 |
|
|
91 |
regex = regex.replaceAll("([^.])[*]", "$1[^/]+"); |
|
92 |
if (regex.startsWith("//")) regex = "(/[^/]+)*/" + regex.substring(2); |
|
93 |
regex = regex.replace("//", "(/[^/]+)*/"); |
|
94 |
regex = regex.replace("node()", "[^/]+"); |
|
95 |
|
|
96 |
try { |
|
97 |
this.p = Pattern.compile(regex); |
|
98 |
if (debug) System.out.println("P="+p); |
|
99 |
} catch(PatternSyntaxException e) { |
|
100 |
String m = NLS.bind("Pattern not compiled correctly with: {0} at {1}.", xpath+" ("+currentXPath+")", hook.getLocation()); |
|
101 |
Log.severe(m); |
|
102 |
Log.severe("Pattern error: "+e); |
|
103 |
Log.printStackTrace(e); |
|
104 |
p = null; |
|
105 |
return false; |
|
106 |
} |
|
107 |
|
|
108 |
return true; |
|
109 |
} |
|
110 |
|
|
111 |
public boolean hasAllXpathsBeenProcessed() { |
|
112 |
return xpaths != null && xpaths.size() == currentXPath; |
|
113 |
} |
|
114 |
|
|
115 |
@Override |
|
116 |
public boolean mustActivate() { |
|
117 |
boolean b = super.mustActivate(); |
|
118 |
if (b) { |
|
119 |
currentXPath++; |
|
120 |
} |
|
121 |
return b; |
|
122 |
} |
|
123 |
|
|
124 |
@Override |
|
125 |
public void hookWasActivated() { |
|
126 |
loadNextXPath(); |
|
127 |
} |
|
128 |
|
|
129 |
public static void main(String[] args) { |
|
130 |
new XPathsHookActivator(null, |
|
131 |
Arrays.asList("//text//p[@name='value']", "//text//p[@name='value']")); |
|
132 |
} |
|
133 |
} |
|
0 | 134 |
Formats disponibles : Unified diff