1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.util;
17
18 import static org.codelibs.core.stream.StreamUtil.split;
19
20 import java.util.Objects;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.codelibs.core.lang.StringUtil;
26 import org.codelibs.core.stream.StreamUtil;
27 import org.codelibs.fess.exception.FessSystemException;
28 import org.w3c.dom.Node;
29
30 public class PrunedTag {
31 private final String tag;
32 private String id;
33 private String css;
34 private String attrName;
35 private String attrValue;
36
37 public PrunedTag(final String tag) {
38 this.tag = tag;
39 }
40
41 public boolean matches(final Node node) {
42 if (tag.equalsIgnoreCase(node.getNodeName())) {
43 if (attrName != null) {
44 final Node attr = node.getAttributes().getNamedItem(attrName);
45 if (attr == null || !attrValue.equals(attr.getNodeValue())) {
46 return false;
47 }
48 }
49 if (id == null) {
50 if (css == null) {
51 return true;
52 }
53 final Node classAttr = node.getAttributes().getNamedItem("class");
54 if (classAttr != null) {
55 final String value = classAttr.getNodeValue();
56 if (StringUtil.isNotBlank(value)) {
57 return StreamUtil.split(value, " ").get(stream -> stream.anyMatch(s -> css.equals(s)));
58 }
59 }
60 } else {
61 final Node idAttr = node.getAttributes().getNamedItem("id");
62 if (idAttr != null) {
63 final String value = idAttr.getNodeValue();
64 return id.equals(value);
65 }
66 }
67 }
68 return false;
69 }
70
71 @Override
72 public int hashCode() {
73 return Objects.hash(css, id, tag);
74 }
75
76 @Override
77 public boolean equals(final Object obj) {
78 if (this == obj) {
79 return true;
80 }
81 if (obj == null) {
82 return false;
83 }
84 if (getClass() != obj.getClass()) {
85 return false;
86 }
87 final PrunedTag other = (PrunedTag) obj;
88 return StringUtils.compare(tag, other.tag) == 0
89 && StringUtils.compare(css, other.css) == 0
90 && StringUtils.compare(id, other.id) == 0
91 && StringUtils.compare(attrName, other.attrName) == 0
92 && StringUtils.compare(attrValue, other.attrValue) == 0;
93 }
94
95 public void setId(final String id) {
96 this.id = id;
97 }
98
99 public void setCss(final String css) {
100 this.css = css;
101 }
102
103 public void setAttr(final String name, final String value) {
104 this.attrName = name;
105 this.attrValue = value;
106 }
107
108 @Override
109 public String toString() {
110 return "PrunedTag [tag=" + tag + ", id=" + id + ", css=" + css + ", attrName=" + attrName + ", attrValue=" + attrValue + "]";
111 }
112
113 public static PrunedTag[] parse(final String value) {
114 return split(value, ",").get(stream -> stream.filter(StringUtil::isNotBlank).map(v -> {
115 final Pattern pattern = Pattern.compile("(\\w+)(\\[[^\\]]+\\])?(\\.[\\w\\-]+)?(#[\\w\\-]+)?");
116 final Matcher matcher = pattern.matcher(v.trim());
117 if (matcher.matches()) {
118 final PrunedTag tag = new PrunedTag(matcher.group(1));
119 if (matcher.group(2) != null) {
120 final String attrPair = matcher.group(2).substring(1, matcher.group(2).length() - 1);
121 final Matcher equalMatcher = Pattern.compile("([\\w\\-]+)=(\\S+)").matcher(attrPair);
122 if (equalMatcher.matches()) {
123 tag.setAttr(equalMatcher.group(1), equalMatcher.group(2));
124 }
125 }
126 if (matcher.group(3) != null) {
127 tag.setCss(matcher.group(3).substring(1));
128 }
129 if (matcher.group(4) != null) {
130 tag.setId(matcher.group(4).substring(1));
131 }
132 return tag;
133 }
134 throw new FessSystemException("Invalid pruned tag: " + v);
135 }).toArray(n -> new PrunedTag[n]));
136 }
137 }