View Javadoc

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 }