View Javadoc
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 }