View Javadoc

1   package net.sf.provisioner.requests;
2   
3   import java.util.Map;
4   
5   import javax.naming.NamingException;
6   import javax.naming.directory.BasicAttribute;
7   import javax.naming.directory.DirContext;
8   import javax.naming.directory.ModificationItem;
9   
10  import net.sf.provisioner.config.ConfigRequest;
11  import net.sf.provisioner.config.LDAPNetworkElement;
12  import net.sf.provisioner.responses.Response;
13  
14  import org.jdom.Document;
15  import org.jdom.Element;
16  
17  
18  /**
19   * Responsible for sending modification requests to external LDAP services.
20   * 
21   * @see Request
22   * 
23   * @author g_pearson
24   *
25   */
26  public class LDAPModifyRequest extends LDAPRequest {
27  
28  	public LDAPModifyRequest(ConfigRequest request, Document opParameters) {
29  		super(request,opParameters);
30  	}
31  
32      /**
33       * Changes the behavior of {@link filterParameters}.  Converts  
34       * parameters into name/LDAP {@link ModificationItem}s.
35       * 
36  	 * All parameters must have the following attributes: name, value, type 
37  	 * (with type being one of "ADD", "REPLACE", or "REMOVE".)  An 
38  	 * {@link IllegalArgumentException} will be thrown if any of these 
39  	 * parameters are missing. 
40  	 * 
41       * @param paramStore the {@linkplain Map} in which parameters should be
42       * stored.
43       * @param element a parameter element from a {@linkplain Request}'s 
44       * operation parameters.
45       * 
46       * @throws IllegalArgumentException if a parameter tag is missing name, 
47       * value, or type attributes.  Also thrown if type is not ADD, REPLACE, 
48       * or REMOVE.
49       */
50  	/* TODO: this allows only one ModificationItem to be stored per
51  	 * attribute.  Add support for specifying arrays of values.
52  	*/
53      protected void storeParameter(Map<String, Object> paramStore, Element element) {
54      	String name      = element.getAttributeValue("name" );
55      	String value     = element.getAttributeValue("value");
56      	String opTypeStr = element.getAttributeValue("type" );
57      	
58      	int opType;
59      	if ("ADD".equalsIgnoreCase(opTypeStr)) {
60      		opType = DirContext.ADD_ATTRIBUTE;
61      	} else if ("REPLACE".equalsIgnoreCase(opTypeStr)) {
62      		opType = DirContext.REPLACE_ATTRIBUTE;
63      	} else if ("REMOVE".equalsIgnoreCase(opTypeStr)) {
64      		opType = DirContext.REMOVE_ATTRIBUTE;
65      	} else {
66      		String message = String.format(
67      				"Parameter for LDAP modify does not contain a valid type.  "
68      				+ "name=%s, value=%s, type=%s",
69      				name, value, opTypeStr
70  			);
71      		throw new IllegalArgumentException(message);    				
72      	}
73      	
74      	ModificationItem item = new ModificationItem(
75      			opType,
76      			new BasicAttribute(name, value)
77      	);
78      	storeParameter(paramStore, name, item);
79      }
80  	
81  	@Override
82  	public Response sendRequest() throws Exception {
83  		DirContext context = ((LDAPNetworkElement) this.ne).findRootContext();
84  		
85  		try {
86  			ModificationItem[] items = params
87  					.values()
88  					.toArray(new ModificationItem[0])
89  			;
90  			
91  			if (logger.isTraceEnabled()) {
92  				logger.trace(
93  						String.format(
94  								"sending LDAP modify request for dn %s, and params: %s", 
95  								getDistinguishedName(), params
96  						)
97  				);
98  			}
99  
100 			context.modifyAttributes(
101 					getDistinguishedName(),
102 					items
103 			);
104 
105 			Response response    = new Response();
106 			response.result      = 
107 			response.errorStr    = "Modified attribute " + getDistinguishedName();
108 			response.retry       = false;
109 			response.successfull = true;
110 			return response;
111 
112 		} catch (NamingException e) {
113 			Response response = new Response();
114 			response.result = "Failed to create attribute.";
115 			
116 			Throwable t = e.getRootCause();
117 			if (t != null) {
118 				// Save the LDAP server's response, if it's there...
119 				response.errorStr = t.getMessage();
120 			} else {
121 				// ... or save Java's error message.
122 				response.errorStr = e.getExplanation();
123 			}
124 			// TODO: find out which errors should result in a retry. 
125 			response.retry       = false;
126 			response.successfull = false;
127 			return response;
128 		} finally {
129 			context.close();			
130 		}				
131 	}
132 }