1 package org.jmage.filterchain;
2
3 import org.jmage.filter.ConfigurableImageFilter;
4 import org.jmage.filter.FilterException;
5 import org.jmage.filter.ImageFilter;
6 import org.jmage.util.ReflectionUtil;
7 import org.jmage.util.TextUtil;
8 import org.jmage.util.XmlUtil;
9 import org.w3c.dom.Document;
10 import org.w3c.dom.Node;
11 import org.w3c.dom.NodeList;
12
13 import javax.naming.directory.NoSuchAttributeException;
14 import java.util.Properties;
15 import java.util.StringTokenizer;
16
17 /***
18 * Creates a FilterChain from serialized xml format, written by FilterChainXmlSerializer. Class is *not* threadsafe.
19 */
20 public class XmlFilterChainDeserializer {
21 protected String chainName;
22 private XmlUtil xmlUtil;
23 private TextUtil textUtil;
24 private ReflectionUtil reflectionUtil;
25
26 private static final String NAME = "name";
27 private static final String PROPERTY = "property";
28 private static final String VALUE = "value";
29 private static final String FILTER = "filter";
30 private static final String FILTERCHAIN = "filterchain";
31 private static final String DESERIALIZE_ERROR = "unable to deserialize filter, cause: ";
32 private static final String CREATION_ERROR = "unable to create filter class: ";
33 private static final String CAUSE = " cause: ";
34 protected static final String DOLLAR = "$";
35 private static final String IMAGE_URI = "IMAGE_URI";
36 private static final String NOT_FOUND = "filterchain not found";
37 private static final String CHAIN = "chain:";
38
39 public XmlFilterChainDeserializer() {
40 xmlUtil = new XmlUtil();
41 textUtil = new TextUtil();
42 reflectionUtil = new ReflectionUtil();
43 }
44
45 public FilterChain deserialize(Document document) throws FilterException {
46 chainName = "";
47 return this.deserialize(document.getDocumentElement());
48 }
49
50 public FilterChain deserialize(Document document, String filterChainName) throws FilterException {
51 chainName = "";
52 return this.deserialize(document.getDocumentElement(), filterChainName);
53 }
54
55 protected FilterChain deserialize(Node filterChainNode) throws FilterException {
56 try {
57 chainName += xmlUtil.getAttribute(filterChainNode, NAME);
58 FilterChain chain = new FilterChain(chainName);
59
60
61 return this.deserializeFilters(filterChainNode, chain);
62 } catch (Exception e) {
63 throw new FilterException(DESERIALIZE_ERROR + e.getMessage());
64 }
65 }
66
67 protected FilterChain deserialize(Node filterChainNode, String filterChainName) throws FilterException {
68 try {
69 chainName = xmlUtil.getAttribute(filterChainNode, NAME);
70 StringTokenizer st = new StringTokenizer(filterChainName, DOLLAR);
71
72 st.nextToken();
73 return deserializeInternalFilterChain(st, filterChainNode);
74 } catch (Exception e) {
75 throw new FilterException(DESERIALIZE_ERROR + e.getMessage());
76 }
77 }
78
79 protected FilterChain deserializeInternalFilterChain(StringTokenizer st, Node documentNode) throws NoSuchAttributeException, FilterException {
80 NodeList filters = documentNode.getChildNodes();
81 for (int i = 0; i <= filters.getLength() - 1; i++) {
82 Node filterNode = filters.item(i);
83 NodeList properties = filterNode.getChildNodes();
84 for (int j = 0; j <= properties.getLength() - 1; j++) {
85 Node propertyNode = properties.item(j);
86 if (PROPERTY.equals(propertyNode.getNodeName())) {
87 String name = xmlUtil.getAttribute(propertyNode, NAME);
88 if (IMAGE_URI.equals(name)) {
89 String value = null;
90 try {
91 value = xmlUtil.getAttribute(propertyNode, VALUE);
92 } catch (NoSuchAttributeException e) {
93 Node filterChainNode = xmlUtil.getNamedChildNode(propertyNode, FILTERCHAIN);
94 value = xmlUtil.getAttribute(filterChainNode, NAME);
95 String subFilterChain = st.nextToken();
96 if (subFilterChain.equals(value)) {
97 if (st.hasMoreTokens()) {
98 chainName += (DOLLAR + subFilterChain);
99 return this.deserializeInternalFilterChain(st, filterChainNode);
100 } else {
101 chainName += DOLLAR;
102 return this.deserialize(filterChainNode);
103 }
104 }
105 }
106 }
107 }
108 }
109 }
110 throw new FilterException(NOT_FOUND);
111 }
112
113 protected FilterChain deserializeFilters(Node documentNode, FilterChain chain) throws NoSuchAttributeException, FilterException {
114 NodeList filters = documentNode.getChildNodes();
115 for (int i = 0; i <= filters.getLength() - 1; i++) {
116 Node filterNode = filters.item(i);
117
118 this.deserializeFilter(filterNode, chain);
119 }
120 return chain;
121 }
122
123 protected void deserializeFilter(Node filterNode, FilterChain chain) throws NoSuchAttributeException, FilterException {
124 if (FILTER.equals(filterNode.getNodeName())) {
125 String filterName = xmlUtil.getAttribute(filterNode, NAME);
126 Properties filterProperties = new Properties();
127 this.deserializeFilterProperties(filterNode, filterProperties);
128
129 ImageFilter filter = this.createFilter(filterName);
130 if (filterProperties.isEmpty()) {
131 chain.addFilter(filter);
132 } else {
133 chain.addFilter((ConfigurableImageFilter) filter, filterProperties);
134 }
135 }
136 }
137
138 protected void deserializeFilterProperties(Node filterNode, Properties filterProperties) throws NoSuchAttributeException {
139 NodeList properties = filterNode.getChildNodes();
140 for (int j = 0; j <= properties.getLength() - 1; j++) {
141 Node propertyNode = properties.item(j);
142 if (PROPERTY.equals(propertyNode.getNodeName())) {
143 String name = xmlUtil.getAttribute(propertyNode, NAME);
144 String value = null;
145 try {
146 value = xmlUtil.getAttribute(propertyNode, VALUE);
147 } catch (NoSuchAttributeException e) {
148 value = deserializeFilterPropertyImageURI(name, propertyNode, value);
149 if (value == null) throw e;
150 }
151 filterProperties.setProperty(name, value);
152 }
153 }
154 }
155
156 protected String deserializeFilterPropertyImageURI(String name, Node filterNode, String value) throws NoSuchAttributeException {
157 if (IMAGE_URI.equals(name)) {
158 Node childFilterChainNode = xmlUtil.getNamedChildNode(filterNode, FILTERCHAIN);
159 chainName += (DOLLAR + xmlUtil.getAttribute(childFilterChainNode, NAME));
160 value = CHAIN + chainName;
161 }
162 return value;
163 }
164
165 protected ImageFilter createFilter(String filterName) throws FilterException {
166 try {
167 return (ImageFilter) reflectionUtil.instantiate(filterName);
168 } catch (Exception e) {
169 throw new FilterException(CREATION_ERROR + filterName +
170 CAUSE + e.getMessage());
171 }
172 }
173 }