View Javadoc

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              //filters
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              //we don't want the first token that equals the file name
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             //dispatcher only filter nodes, skip cdata
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 }