1 /**
2 *
3 */
4 package net.sf.provisioner.requests;
5
6 import java.util.ArrayList;
7 import java.util.Collection;
8 import java.util.HashMap;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.Map;
12
13 import javax.lang.model.util.Elements;
14 import javax.naming.directory.ModificationItem;
15
16 import net.sf.provisioner.config.ConfigRequest;
17 import net.sf.provisioner.config.NetworkElement;
18 import net.sf.provisioner.core.Consumer;
19 import net.sf.provisioner.core.Operation;
20 import net.sf.provisioner.core.Producer;
21 import net.sf.provisioner.responses.Response;
22
23 import org.apache.log4j.Logger;
24 import org.jdom.Document;
25 import org.jdom.Element;
26
27 /**
28 * <p>Base class for requests to external services.</p>
29 *
30 * <p>A {@link Producer} reads requests from an external queue, and creates
31 * {@link Operation}s from their information.
32 *
33 * The operation is passed to a {@link Consumer}, which populates the
34 * operation's set of {@link ConfigRequests} (a single operation may require
35 * multiple requests to multiple end-points.)
36 *
37 * The consumer then uses a {@link RequestFactory} to convert each
38 * {@linkplain ConfigRequest} into a {@linkplain Request}, which is
39 * executed, and examine for a successful response.
40 * </p>
41 *
42 * @version $Revision: 1.1.2.2 $, $Date: 2007/11/13 22:36:03 $
43 * @author Gonzalo Espert
44 * @author G. Pearson
45 */
46 public abstract class Request {
47
48 /** Logger for this class and subclasses */
49 Logger logger = Logger.getLogger(getClass());
50
51 /* Elemento de red del requerimiento */
52 NetworkElement ne = new NetworkElement();
53
54
55 public abstract Response sendRequest() throws Exception;
56
57 /**
58 * Convenience method for extending classes. Takes a set of XML elements
59 * and finds all "parameter" tags.
60 * Stores found parameters in a {@linkplain Map}. Extending classes
61 * have can modify the results of this method by overriding the
62 * <code>storeParameter</code> methods.
63 *
64 * @param opParameters an XML document detailing parameters from an
65 * operation. Typically, these will come from a request fetched from
66 * the database.
67 *
68 * @return a {@linkplain Map} of parameter values.
69 */
70 protected Map<String, Object> filterParameters(Document opParameters) {
71 Collection<Element> operationElements = filterElements(
72 opParameters.getContent().iterator(), "operation"
73 );
74
75 Map<String, Object> result = new HashMap<String, Object>();
76 /* TODO: find out if we assume that there will only be one operation
77 * per request? */
78 for (Element opElement : operationElements) {
79 Collection<Element> params = filterElements(
80 opElement.getContent().iterator(), "parameter"
81 );
82
83 for (Element param : params) {
84 storeParameter(
85 result,
86 param.getAttributeValue("name"),
87 param.getAttributeValue("value")
88 );
89 }
90 }
91 return result;
92 }
93
94 /**
95 * Called by {@link filterParameters} when building a {@linkplain Map}
96 * of request parameters. By default, this simply calls
97 * {@link storeParameter(Map,String,String)} with the element's
98 * <code>name</code> and <code>value</code> attributes. Extending classes
99 * may choose to store extra information (e.g. LDAPModifyRequest converts
100 * parameters into {@link ModificationItem}s.)
101 *
102 * @param paramStore the {@linkplain Map} that any parameters should be
103 * stored in.
104 * @param element a parameter element from a {@linkplain Request}'s
105 * operation parameters.
106 *
107 */
108 protected void storeParameter(Map<String, Object> paramStore, Element element) {
109 storeParameter(
110 paramStore,
111 element.getAttributeValue("name"),
112 element.getAttributeValue("value")
113 );
114 }
115
116 /**
117 * The default method for processing request parameters. Stores the
118 * parameter name and value in <code>paramStore</code>.
119 *
120 * @param paramStore the {@linkplain Map} that any parameters should be
121 * stored in.
122 * @param name the name of the operation parameter.
123 * @param value the value of the named operation parameter.
124 */
125 protected void storeParameter(Map<String, Object> paramStore, String name, Object value) {
126 List<Object> storedValue = (List<Object>) paramStore.get(name);
127 if (storedValue == null) {
128 // Create a list for this key value and store it in the paramStore.
129 storedValue = new ArrayList<Object>();
130 paramStore.put(name, storedValue);
131 }
132
133 storedValue.add(value);
134 }
135
136 /**
137 * Filters {@linkplaiun Element}'s by comparing
138 * {@link Element#getName()} with <code>matchingName</code>
139 * (simple equalsIgnoreCase comparison.)
140 *
141 * @param i an iterator for a collection of {@linkplain Elements}.
142 * @param matchingName the value that elements are filtered by.
143 * @return a collection of elements with names that match <code>matchingName</code>
144 */
145 protected Collection<Element> filterElements(Iterator<Element> i, String matchingName) {
146 if (matchingName == null) {
147 throw new IllegalArgumentException("matchingName cannot be null.");
148 }
149
150 List<Element> result = new ArrayList<Element>();
151 while (i.hasNext()) {
152 Element child = i.next();
153 if (matchingName.equalsIgnoreCase(child.getName())) {
154 result.add(child);
155 }
156 }
157 return result;
158 }
159 }