| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.oodt.grid; |
| |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| /** |
| * Controller servlet for making changes to configuration. |
| */ |
| public class ConfigServlet extends GridServlet { |
| /** |
| * Handle updates to a configuration by saving them and directing back to the |
| * config page. |
| * |
| * @param req |
| * a <code>HttpServletRequest</code> value. |
| * @param res |
| * a <code>HttpServletResponse</code> value. |
| * @throws ServletException |
| * if an error occurs. |
| * @throws IOException |
| * if an error occurs. |
| */ |
| public void doPost(HttpServletRequest req, HttpServletResponse res) |
| throws ServletException, IOException { |
| Configuration config = getConfiguration(); // Get the singleton |
| // configuration |
| if (!approveAccess(config, req, res)) |
| return; // Check if the user can access this page |
| |
| ConfigBean cb = getConfigBean(req); // Get the bean |
| cb.setMessage(""); // Clear out any message |
| if (!cb.isAuthentic()) |
| throw new ServletException(new AuthenticationRequiredException()); |
| boolean needSave = false; // Assume no changes for now |
| |
| String newPass = req.getParameter("password"); // See if she wants to change |
| // password |
| if (newPass != null && newPass.length() > 0) { // Got a password, and it's |
| // not empty? |
| config.setPassword(newPass.getBytes()); // Yes, set its bytes |
| needSave = true; // We need to save |
| } |
| |
| boolean https = config.isHTTPSrequired(); // Are we currently using https? |
| String httpsParam = req.getParameter("https"); // Get her https param |
| boolean newHttps = httpsParam != null && "on".equals(httpsParam); // See if |
| // she |
| // wants |
| // to use |
| // https |
| // or not |
| if (https != newHttps) { // Different? |
| config.setHTTPSrequired(newHttps); // Yes, set the new state |
| needSave = true; // We need to save |
| } |
| |
| boolean local = config.isLocalhostRequired(); // Are we requiring localhost? |
| String localhostParam = req.getParameter("localhost"); // Get her localhost |
| // param |
| boolean newLocal = localhostParam != null && "on".equals(localhostParam); // See |
| // if |
| // she |
| // wants |
| // to |
| // require |
| // localhost |
| if (local != newLocal) { // Different? |
| config.setLocalhostRequired(newLocal); // Yes, set the new state |
| needSave = true; // We need to save |
| } |
| |
| String newKey = req.getParameter("newkey"); // See if she's got a new |
| // property |
| if (newKey != null && newKey.length() > 0) { // And make sure it's nonempty |
| String newVal = req.getParameter("newval"); // Got one, get its value |
| if (newVal == null) |
| newVal = ""; // Make sure it's at least an empty string |
| config.getProperties().setProperty(newKey, newVal); // Set the new |
| // property |
| needSave = true; // We need to save |
| } |
| |
| needSave |= updateProperties(config.getProperties(), // Make any updates to |
| // existing property |
| req.getParameterMap()); // values, and see note if we need to save |
| try { |
| needSave |= updateServers(config, req.getParameterMap(), 'd'); // Same |
| // goes for |
| // product |
| // servers |
| needSave |= updateServers(config, req.getParameterMap(), 'm'); // And |
| // profile |
| // servers |
| needSave |= updateCodeBases(config, req.getParameterMap()); // And for |
| // code bases |
| } catch (MalformedURLException ex) { // Make sure code base URLs are OK |
| cb.setMessage("Code bases must be valid URLs (" // Not OK? |
| + ex.getMessage() + "); no changes made"); // Let user know via a |
| // message |
| req.getRequestDispatcher("config.jsp").forward(req, res); // And make no |
| // changes until |
| // she fixes it |
| return; |
| } |
| |
| if (needSave) { // Do we need to save? |
| config.save(); // Then do it already! |
| cb.setMessage("Changes saved."); // And let the user know |
| } else { |
| cb.setMessage("No changes made."); // Oh, no changes were made, let user |
| // know |
| } |
| req.getRequestDispatcher("config.jsp").forward(req, res); // Back to the |
| // config page |
| } |
| |
| /** |
| * Update changes to the code bases. |
| * |
| * @param config |
| * a <code>Configuration</code> value. |
| * @param params |
| * a <code>Map</code> value. |
| * @return True if changes need to be saved. |
| * @throws MalformedURLException |
| * if an error occurs. |
| */ |
| private boolean updateCodeBases(Configuration config, Map params) |
| throws MalformedURLException { |
| boolean needSave = false; // Assume no change |
| List codeBases = config.getCodeBases(); // Get the current code bases |
| |
| List toRemove = new ArrayList(); // Hold indexes of code bases to remove |
| for (Iterator i = params.entrySet().iterator(); i.hasNext();) { // For each |
| // parameter |
| Map.Entry entry = (Map.Entry) i.next(); // Get its entry |
| String key = (String) entry.getKey(); // And its name |
| String value = ((String[]) entry.getValue())[0]; // And its zeroth value |
| if (key.startsWith("delcb-") && "on".equals(value)) { // If it's checked |
| Integer index = new Integer(key.substring(6)); // Parse out the index |
| toRemove.add(index); // Add it to the list |
| } |
| } |
| if (!toRemove.isEmpty()) { // And if we have any indexes |
| Collections.sort(toRemove); // Sort 'em and put 'em in reverse ... |
| Collections.reverse(toRemove); // ... order so we can safely remove them |
| for (Iterator i = toRemove.iterator(); i.hasNext();) { // For each index |
| // to remove |
| int index = ((Integer) i.next()).intValue(); // Get the index value |
| codeBases.remove(index); // And buh-bye. |
| } |
| needSave = true; // Definitely need to save changes now |
| } |
| |
| String[] newCBs = (String[]) params.get("newcb"); // Was there a new code |
| // base specified? |
| if (newCBs != null && newCBs.length == 1) { // And was there exactly one |
| // value? |
| String newCB = newCBs[0]; // Get that exactly one value |
| if (newCB != null && newCB.length() > 0) { // Is it nonnull and nonempty? |
| URL newURL = new URL(newCB); // Treat is as an URL |
| codeBases.add(newURL); // Add it to the list |
| needSave = true; // Ad we gotta save |
| } |
| } |
| return needSave; |
| } |
| |
| /** |
| * Update the list of product/profile servers based on request parameters. |
| * |
| * @param config |
| * System configuration |
| * @param params |
| * Request parameters. |
| * @param type |
| * <code>d</code> (data) if product servers, <code>m</code> |
| * (metadata) if profile servers |
| * @return True if any changes were made, false if no changes were made |
| */ |
| private boolean updateServers(Configuration config, Map params, char type) { |
| List servers = type == 'd' ? config.getProductServers() : config |
| .getProfileServers(); |
| boolean needSave = false; // Assume no changes for now |
| |
| List toRemove = new ArrayList(); // Start with empty list of indexes to |
| // remove |
| for (Iterator i = params.entrySet().iterator(); i.hasNext();) { // Go |
| // through |
| // each |
| // parameter |
| Map.Entry entry = (Map.Entry) i.next(); // Get its key/value |
| String name = (String) entry.getKey(); // The key is a String |
| if (name.startsWith(type + "rm-")) { // Is it an "drm-" or "mrm-"? |
| Integer index = new Integer(name.substring(4)); // Yes, get it sindex |
| toRemove.add(index); // Add it to the list |
| } |
| } |
| |
| if (!toRemove.isEmpty()) { // Got any to remove? |
| Collections.sort(toRemove); // We need to go through them in reverse ord- |
| Collections.reverse(toRemove); // -er, so that removals don't shift |
| // indexes |
| for (Iterator i = toRemove.iterator(); i.hasNext();) { // For each index |
| int index = ((Integer) i.next()).intValue(); // Get its int value |
| servers.remove(index); // and buh-bye |
| } |
| needSave = true; // Gotta save after all that, whew. |
| } |
| |
| if (params.containsKey(type + "-newcn")) { // Adding a new server? |
| String[] newClasses = (String[]) params.get(type + "-newcn"); // And the |
| // new class |
| // name |
| if (newClasses != null && newClasses.length == 1) { // Are present and |
| // there's only one of |
| // each |
| String newClass = newClasses[0]; // Get the new class |
| if (newClass != null && newClass.length() > 0) { // And nonempty |
| Server server; |
| if (type == 'd') // If it's data |
| server = new ProductServer(config, newClass); // It's a product |
| // server |
| else |
| // otherwise it's metadata |
| server = new ProfileServer(config, newClass); // Which is a profile |
| // server |
| servers.add(server); // Add it to the set of servers |
| needSave = true; // And after all this, we need to save! |
| } |
| } |
| } |
| |
| return needSave; |
| } |
| |
| /** |
| * Update properties based on request parameters. |
| * |
| * @param props |
| * <code>Properties</code> to update |
| * @param params |
| * Request parameters |
| * @return True if changes need to be saved, false otherwise |
| */ |
| private boolean updateProperties(Properties props, Map params) { |
| boolean needSave = false; // Assume no save for now |
| for (Iterator i = params.entrySet().iterator(); i.hasNext();) { // Go |
| // through |
| // each |
| // request |
| // parameter |
| Map.Entry entry = (Map.Entry) i.next(); // Get the key/value |
| String name = (String) entry.getKey(); // Key is always a string |
| String newValue = ((String[]) entry.getValue())[0]; // Value is String[], |
| // get the zeroth |
| if (name.startsWith("val-")) { // If the param is "val-" |
| String key = name.substring(4); // Then find the key |
| if (props.containsKey(key)) { // If that key exists |
| String value = props.getProperty(key); // Find its value |
| if (value == null || !value.equals(newValue)) {// Are they different? |
| props.setProperty(key, newValue); // Yes, set the new value |
| needSave = true; // And we need to save |
| } |
| } |
| } else if (name.startsWith("del-")) { // If the param is "del-" |
| String key = name.substring(4); // Then find the key |
| if (props.containsKey(key)) { // If that key exists |
| props.remove(key); // Then remove its mapping |
| needSave = true; // And we need to save |
| } |
| } |
| } |
| return needSave; |
| } |
| } |