1 /*
2 * Copyright 2012 Olivier Godineau
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations under
12 * the License.
13 */
14 package olg.csv.bean.loader.getter;
15
16 import javax.xml.xpath.XPathConstants;
17 import javax.xml.xpath.XPathExpressionException;
18
19 import olg.csv.bean.getter.AbstractGetter;
20 import olg.csv.bean.loader.LoadException;
21 import olg.csv.bean.loader.Util;
22 import olg.csv.bean.loader.filter.AbstractFiltreLoader;
23 import olg.csv.bean.loader.getter.impl.ConcateGetterLoader;
24 import olg.csv.bean.loader.getter.impl.ConstantGetterLoader;
25 import olg.csv.bean.loader.getter.impl.CustomGetterLoader;
26 import olg.csv.bean.loader.getter.impl.DefaultGetterLoader;
27
28 import org.w3c.dom.Attr;
29 import org.w3c.dom.Element;
30 import org.w3c.dom.Node;
31
32 /**
33 * Class dedicated to load a getter {@link AbstractGetter} from an XML element
34 * conformed to XML schema GetterType specification. Each concret class shall
35 * have the responsibility to load a concrete AbstractGetter class.
36 *
37 * <p>
38 * Class based on Chain of responsability pattern and used to chain concret
39 * Getter Loaders.
40 * </p>
41 *
42 * @author Olivier Godineau
43 * @see AbstractGetter
44 */
45 public abstract class AbstractGetterLoader {
46
47 /**
48 * Singleton responsible of getters loading.
49 */
50 private static AbstractGetterLoader instance = new DefaultGetterLoader(new ConcateGetterLoader(
51 new ConstantGetterLoader(new CustomGetterLoader(null))));
52
53 /**
54 * Returns singleton responsible of getters loading
55 *
56 * This is this instance you have to be used to load every type of getter
57 * from XML element conformed to XML Schema GetterType specification.
58 *
59 * @return the getters loader.
60 */
61 public static AbstractGetterLoader getInstance() {
62 return instance;
63 }
64
65 /**
66 * GetterLoader successor as describe in Chain of responsability pattern.
67 */
68 protected AbstractGetterLoader successor;
69
70 /**
71 * This Xpath expression allows to identify xml node which describe the
72 * corresponding concret filter under Fitler Type node.
73 */
74 protected String xPathExpression;
75
76 /**
77 * Returns a concret getter identified from the given XML element.
78 *
79 * @param element
80 * XML node corresponding to correspondant to XML GetterType as
81 * described in our XML schema.
82 * @return a concret getter or <code>null</code> if the given element
83 * doesn't match concret getter type this loader has responsability
84 * and doesn't match any successor
85 * @throws XPathExpressionException
86 * on invalid XPathExpression
87 * @throws LoadException
88 * on Error occurs during loading
89 */
90 public final AbstractGetter getGetter(Element element) throws XPathExpressionException, LoadException {
91 AbstractGetter retour = null;
92 String defaultValue = null;
93 if (element != null) {
94 Attr attr = element.getAttributeNode("default");
95 if (attr != null) {
96 defaultValue = attr.getTextContent();
97 }
98 Node node = (Node) Util.evaluerDOM(element, xPathExpression, XPathConstants.NODE);
99 if (node != null) { // NOPMD by olivier on 01/02/12 00:44
100 retour = getConcreteGetter((Element) node, defaultValue);
101 node = (Node) Util.evaluerDOM(element, "filter", XPathConstants.NODE);
102 retour.setFilter(AbstractFiltreLoader.getInstance().getFilter((Element) node));
103
104 } else {
105 if (successor != null) {
106 retour = successor.getGetter(element);
107 }
108 }
109 }
110 return retour;
111 }
112
113 /**
114 * Returns a concret getter.
115 *
116 * @param node
117 * XML Element corresponding to the XPath expression from which
118 * the corresponding getter is loaded.
119 * @param defaultValue
120 * value the loaded getter must used as default value.
121 * @return a concret getter this loader has responsability or
122 * <code>null</code> if the given node doesn't match the type this
123 * loader should return.
124 * @throws XPathExpressionException
125 * on invalid XPathExpression
126 * @throws LoadException
127 * on Error occurs during loading
128 * @see #xPathExpression
129 */
130 protected abstract AbstractGetter getConcreteGetter(Element node, String defaultValue)
131 throws XPathExpressionException, LoadException;
132
133 /**
134 *
135 * @param xPathExpression
136 * XPath expression that allows to identify the concret getter
137 * under the XML GetterType node
138 * @param successor
139 * following concret loader in the chain of responsability
140 *
141 */
142 protected AbstractGetterLoader(String xPathExpression, AbstractGetterLoader successor) {
143 super();
144 this.successor = successor;
145 this.xPathExpression = xPathExpression;
146 }
147 }