org.apache.felix.webconsole.internal.compendium.ConfigManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.felix.webconsole.internal.compendium.ConfigManager.java

Source

/*
 * 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.felix.webconsole.internal.compendium;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.servlet.OsgiManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONWriter;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.cm.ManagedServiceFactory;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.ObjectClassDefinition;

/**
 * The <code>ConfigManager</code> TODO
 */
public class ConfigManager extends ConfigManagerBaseServ {

    private static class PlaceholderConfiguration implements Configuration {

        private final String factoryPid;
        private String bundleLocation;

        PlaceholderConfiguration(String factoryPid) {
            this.factoryPid = factoryPid;
        }

        public void delete() {
            // dummy configuration cannot be deleted
        }

        public String getBundleLocation() {
            return bundleLocation;
        }

        public String getFactoryPid() {
            return factoryPid;
        }

        public String getPid() {
            return SAVED_PID;
        }

        public Dictionary getProperties() {
            // dummy configuration has no properties
            return null;
        }

        public void setBundleLocation(String bundleLocation) {
            this.bundleLocation = bundleLocation;
        }

        public void update() {
            // dummy configuration cannot be updated
        }

        public void update(Dictionary properties) {
            // dummy configuration cannot be updated
        }

    }

    private static final String PID_FILTER = "pidFilter";

    public static final String CONFIG_NAME = "configMgr";

    public static final String LABEL = "Configuration";

    public static final String SERVICE_PID = "pid";

    public static final String factoryPID = "factoryPid";

    private static final String SAVED_PID = "[Temporary PID replaced by real PID upon save]";
    private static final int TAIL_LENGTH = 5;

    private static final int STRING_FORWARD = 1;

    private void addConfigurationInfo(Configuration config, JSONWriter json, String locale) throws JSONException {

        if (config.getFactoryPid() != null) {
            json.key(factoryPID);
            json.value(config.getFactoryPid());
        }

        String currLocation;
        if (config.getBundleLocation() == null) {
            currLocation = "None";
        } else {
            Bundle currBundle = this.getBundle(config.getBundleLocation());

            Dictionary headersBook = currBundle.getHeaders(locale);
            String name = (String) headersBook.get(Constants.BUNDLE_NAME);
            if (name == null) {
                currLocation = currBundle.getSymbolicName();
            } else {
                currLocation = name + " (" + currBundle.getSymbolicName() + ")";
            }

            Version currVersion = Version.parseVersion((String) headersBook.get(Constants.BUNDLE_VERSION));
            currLocation += ", Version " + currVersion.toString();
        }
        json.key("bundleLocation");
        json.value(currLocation);
    }

    private String applyConfiguration(HttpServletRequest comingRequest, ConfigurationAdmin ca, String pid)
            throws IOException {
        if (comingRequest.getParameter("delete") != null) {
            // only delete if the PID is not our place holder
            if (!SAVED_PID.equals(pid)) {
                // TODO: should log this here !!
                Configuration config = ca.getConfiguration(pid, null);
                config.delete();
            }
            return comingRequest.getHeader("Referer");
        }

        String factoryPid = comingRequest.getParameter(ConfigManager.factoryPID);
        Configuration tempConfig = null;

        String propertyList = comingRequest.getParameter("propertylist");
        if (propertyList == null) {
            String propertiesString = comingRequest.getParameter("properties");

            if (propertiesString != null) {
                byte[] propBytes = propertiesString.getBytes("ISO-8859-1");
                ByteArrayInputStream bin = new ByteArrayInputStream(propBytes);
                Properties props = new Properties();
                props.load(bin);

                tempConfig = getConfiguration(ca, pid, factoryPid);
                tempConfig.update(props);
            }
        } else {
            tempConfig = getConfiguration(ca, pid, factoryPid);

            Dictionary propsBook = tempConfig.getProperties();
            if (propsBook == null) {
                propsBook = new Hashtable();
            }

            Map attrDefMap = this.getAttributeDefinitionMap(tempConfig, null);
            if (attrDefMap != null) {
                StringTokenizer propTokens = new StringTokenizer(propertyList, ",");
                while (propTokens.hasMoreTokens()) {
                    String propName = propTokens.nextToken();
                    AttributeDefinition currAttrDef = (AttributeDefinition) attrDefMap.get(propName);
                    if (currAttrDef == null || (currAttrDef.getCardinality() == 0
                            && currAttrDef.getType() == AttributeDefinition.STRING)) {
                        String currPropName = comingRequest.getParameter(propName);
                        if (currPropName != null) {
                            propsBook.put(propName, currPropName);
                        }
                    } else if (currAttrDef.getCardinality() == 0) {
                        // scalar of non-string
                        String curProp = comingRequest.getParameter(propName);
                        if (curProp != null) {
                            try {
                                propsBook.put(propName, this.getType(currAttrDef.getType(), curProp));
                            } catch (NumberFormatException nfe) {
                                // don't care
                            }
                        }
                    } else {
                        // array or vector of any type
                        Vector tempVec = new Vector();

                        String[] properties = comingRequest.getParameterValues(propName);
                        if (properties != null) {
                            for (int i = 0; i < properties.length; i++) {
                                try {
                                    tempVec.add(this.getType(currAttrDef.getType(), properties[i]));
                                } catch (NumberFormatException nfe) {
                                    // don't care
                                }
                            }
                        }

                        // but ensure size
                        int maxSize = Math.abs(currAttrDef.getCardinality());
                        if (tempVec.size() > maxSize) {
                            tempVec.setSize(maxSize);
                        }

                        if (currAttrDef.getCardinality() < 0) {
                            // keep the vector
                            propsBook.put(propName, tempVec);
                        } else {
                            // convert to an array
                            propsBook.put(propName, this.getArray(currAttrDef.getType(), tempVec));
                        }
                    }
                }
            }

            tempConfig.update(propsBook);
        }

        // redirect to the new configuration (if existing)
        return (tempConfig != null) ? tempConfig.getPid() : "";
    }

    private void configForm(JSONWriter jsonWriter, String inputPid, Configuration config, String pidFilter,
            String locale) throws JSONException {

        jsonWriter.key(ConfigManager.SERVICE_PID);
        jsonWriter.value(inputPid);

        if (pidFilter != null) {
            jsonWriter.key(PID_FILTER);
            jsonWriter.value(pidFilter);
        }

        Dictionary propsDictionary = null;
        ObjectClassDefinition classDef;
        if (config != null) {
            propsDictionary = config.getProperties();
            classDef = this.getObjectClassDefinition(config, locale);
        } else {
            classDef = this.getObjectClassDefinition(inputPid, locale);
        }

        propsDictionary = this.mergeWithMetaType(propsDictionary, classDef, jsonWriter);

        if (propsDictionary != null) {

            jsonWriter.key("title");
            jsonWriter.value(inputPid);
            jsonWriter.key("description");
            jsonWriter.value(
                    "Please enter configuration properties for this configuration in the field below. This configuration has no associated description");

            jsonWriter.key("propertylist");
            jsonWriter.value("properties");

            jsonWriter.key("properties");
            jsonWriter.object();
            for (Enumeration propEnum = propsDictionary.keys(); propEnum.hasMoreElements();) {
                Object nextElement = propEnum.nextElement();

                // ignore well known special properties
                if (!nextElement.equals(Constants.SERVICE_PID) && !nextElement.equals(Constants.SERVICE_DESCRIPTION)
                        && !nextElement.equals(Constants.SERVICE_ID)
                        && !nextElement.equals(Constants.SERVICE_RANKING)
                        && !nextElement.equals(ConfigurationAdmin.SERVICE_FACTORYPID)
                        && !nextElement.equals(Constants.SERVICE_VENDOR)
                        && !nextElement.equals(ConfigurationAdmin.SERVICE_BUNDLELOCATION)) {
                    jsonWriter.key(String.valueOf(nextElement));
                    jsonWriter.value(propsDictionary.get(nextElement));
                }
            }
            jsonWriter.endObject();

        }

        if (config != null) {
            this.addConfigurationInfo(config, jsonWriter, locale);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // let's check for a json request
        final String currInfo = request.getPathInfo();
        if (currInfo.endsWith(".json")) {
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");

            // after last slash and without extension
            String tempPid = currInfo.substring(currInfo.lastIndexOf('/') + 1, currInfo.length() - TAIL_LENGTH);
            // check whether the pid is actually a filter for the selection
            // of configurations to display
            String pidFilter = request.getParameter(PID_FILTER);
            if (pidFilter == null) {
                pidFilter = tempPid;
            }
            try {
                getBundleContext().createFilter(pidFilter);

                // if the pidFilter was set from the pid, clear the pid
                if (tempPid == pidFilter) {
                    tempPid = null;
                }
            } catch (InvalidSyntaxException ex) {
                pidFilter = null;
            }

            final ConfigurationAdmin currConfigAdmin = this.getConfigurationAdmin();

            final Locale currLocale = getLocale(request);
            final String localeInfo = (currLocale != null) ? currLocale.toString() : null;

            final PrintWriter printWriter = response.getWriter();

            try {
                printWriter.write("[");
                final SortedMap tempServices = this.getServices(tempPid, pidFilter, localeInfo, false);
                final Iterator tempIter = tempServices.keySet().iterator();
                boolean moreConfig = false;
                while (tempIter.hasNext()) {
                    final String servicePid = tempIter.next().toString();

                    final Configuration config = this.getConfigurationWithPid(currConfigAdmin, servicePid);
                    if (config != null) {
                        if (moreConfig) {
                            printWriter.print(',');
                        }
                        this.printJsonConfig(printWriter, servicePid, config, pidFilter, localeInfo);
                        moreConfig = true;
                    }
                }
                printWriter.write("]");
            } catch (InvalidSyntaxException ex) {
                // this should not happend as we checked the filter before
            }
            // nothing more to do
            return;
        }

        super.doGet(request, response);
    }

    protected void doPost(HttpServletRequest comingrequest, HttpServletResponse response) throws IOException {
        // needed multiple times below
        String tempPid = comingrequest.getParameter(ConfigManager.SERVICE_PID);
        if (tempPid == null) {
            String pathInfo = comingrequest.getPathInfo();
            tempPid = pathInfo.substring(pathInfo.lastIndexOf('/') + STRING_FORWARD);
        }

        // the filter to select part of the configurations
        String pidFilterParam = comingrequest.getParameter(PID_FILTER);

        final ConfigurationAdmin currConfigAdmin = this.getConfigurationAdmin();

        // ignore this request if the pid and/or configuration admin is missing
        if (tempPid == null || currConfigAdmin == null) {
            // should log this here !!
            return;
        }

        // the configuration to operate on (to be created or "missing")
        Configuration tempConfig = null;

        // should actually apply the configuration before redirecting
        if (comingrequest.getParameter("create") != null) {
            tempConfig = new PlaceholderConfiguration(tempPid); // ca.createFactoryConfiguration(
            // pid, null );
            tempPid = tempConfig.getPid();
        } else if (comingrequest.getParameter("apply") != null) {
            String redirectAddr = applyConfiguration(comingrequest, currConfigAdmin, tempPid);
            if (redirectAddr != null) {
                if (pidFilterParam != null) {
                    redirectAddr += "?" + PID_FILTER + "=" + pidFilterParam;
                }

                this.sendRedirectURL(comingrequest, response, redirectAddr);
            }

            return;
        }

        if (tempConfig == null) {
            tempConfig = getConfigurationWithPid(currConfigAdmin, tempPid);
        }

        // send the result
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        final Locale requestLocale = getLocale(comingrequest);
        final String localeInfo = (requestLocale != null) ? requestLocale.toString() : null;
        printJsonConfig(response.getWriter(), tempPid, tempConfig, pidFilterParam, localeInfo);
    }

    private Object getArray(int type, Vector values) {
        int totalSize = values.size();

        // short cut for string array
        if (type == AttributeDefinition.STRING) {
            return values.toArray(new String[totalSize]);
        }

        Object tempArray;
        switch (type) {
        case AttributeDefinition.FLOAT:
            tempArray = new float[totalSize];
        case AttributeDefinition.LONG:
            tempArray = new long[totalSize];
        case AttributeDefinition.INTEGER:
            tempArray = new int[totalSize];
        case AttributeDefinition.SHORT:
            tempArray = new short[totalSize];
        case AttributeDefinition.BOOLEAN:
            tempArray = new boolean[totalSize];
        case AttributeDefinition.BYTE:
            tempArray = new byte[totalSize];
        case AttributeDefinition.CHARACTER:
            tempArray = new char[totalSize];
        case AttributeDefinition.DOUBLE:
            tempArray = new double[totalSize];

        default:
            // unexpected, but assume string
            tempArray = new String[totalSize];
        }

        for (int i = 0; i < totalSize; i++) {
            Array.set(tempArray, i, values.get(i));
        }

        return tempArray;
    }

    private Configuration getConfiguration(ConfigurationAdmin ca, String pid, String factoryPid)
            throws IOException {
        if (factoryPid != null && (pid == null || pid.equals(SAVED_PID))) {
            return ca.createFactoryConfiguration(factoryPid, null);
        }

        return ca.getConfiguration(pid, null);
    }

    private Configuration getConfigurationWithPid(ConfigurationAdmin configAdmin, String comingPid) {
        if (configAdmin != null && comingPid != null) {
            try {
                // we use listConfigurations to not create configuration
                // objects persistently without the user providing actual
                // configuration
                String filter = "(" + Constants.SERVICE_PID + "=" + comingPid + ")";
                Configuration[] filterConfigs = configAdmin.listConfigurations(filter);
                if (filterConfigs != null && filterConfigs.length > 0) {
                    return filterConfigs[0];
                }
            } catch (InvalidSyntaxException synEx) {
                // should print message
            } catch (IOException ioEx) {
                // should print message
            }
        }

        // fallback to no configuration at all
        return null;
    }

    private SortedMap getServices(String inputService, String currServiceFilter, String localeInfo,
            boolean ocdRequired) throws InvalidSyntaxException {
        // sorted map of options
        SortedMap currOptFactory = new TreeMap(String.CASE_INSENSITIVE_ORDER);

        // find all ManagedServiceFactories to get the factoryPIDs
        ServiceReference[] currServRefList = this.getBundleContext().getServiceReferences(inputService,
                currServiceFilter);
        for (int i = 0; currServRefList != null && i < currServRefList.length; i++) {
            Object pidObject = currServRefList[i].getProperty(Constants.SERVICE_PID);
            if (pidObject instanceof String) {
                String tempPid = (String) pidObject;
                String workerName;
                final ObjectClassDefinition classDef = this.getObjectClassDefinition(currServRefList[i].getBundle(),
                        tempPid, localeInfo);
                if (classDef != null) {
                    workerName = classDef.getName() + " (";
                    workerName += tempPid + ")";
                } else {
                    workerName = tempPid;
                }

                if (!ocdRequired || classDef != null) {
                    currOptFactory.put(tempPid, workerName);
                }
            }
        }

        return currOptFactory;
    }

    public String getServletCapital() {
        return LABEL;
    }

    public String getServletLabel() {
        return CONFIG_NAME;
    }

    /**
     * @throws NumberFormatException
     *             If the value cannot be converted to a number and type
     *             indicates a numeric type
     */
    private Object getType(int type, String value) {
        switch (type) {
        case AttributeDefinition.BYTE:
            return Byte.valueOf(value);
        case AttributeDefinition.CHARACTER:
            char c = (value.length() > 0) ? value.charAt(0) : 0;
            return new Character(c);
        case AttributeDefinition.BOOLEAN:
            return Boolean.valueOf(value);
        case AttributeDefinition.LONG:
            return Long.valueOf(value);
        case AttributeDefinition.INTEGER:
            return Integer.valueOf(value);
        case AttributeDefinition.SHORT:
            return Short.valueOf(value);
        case AttributeDefinition.DOUBLE:
            return Double.valueOf(value);
        case AttributeDefinition.FLOAT:
            return Float.valueOf(value);

        default:
            // includes AttributeDefinition.STRING
            return value;
        }
    }

    private void listConfigurations(PrintWriter printWriter, ConfigurationAdmin inputConfigAdmin,
            String inputPidFilter, String localeInfo) {
        try {
            // start with ManagedService instances
            SortedMap currOptionsPlain = getServices(ManagedService.class.getName(), inputPidFilter, localeInfo,
                    true);

            // add in existing configuration (not duplicating ManagedServices)
            Configuration[] tempConfigsList = inputConfigAdmin.listConfigurations(inputPidFilter);
            for (int i = 0; tempConfigsList != null && i < tempConfigsList.length; i++) {

                // ignore configuration object if an entry already exists in the
                // map
                String tempPid = tempConfigsList[i].getPid();
                if (currOptionsPlain.containsKey(tempPid)) {
                    continue;
                }

                // insert and entry for the pid
                ObjectClassDefinition classDef = this.getObjectClassDefinition(tempConfigsList[i], localeInfo);
                String tempName;
                if (classDef != null) {
                    tempName = classDef.getName() + " (";
                    tempName += tempPid + ")";
                } else {
                    tempName = tempPid;
                }

                if (classDef != null) {
                    currOptionsPlain.put(tempPid, tempName);
                }
            }

            printOptionsForm(printWriter, currOptionsPlain, "configSelection_pid", "configure", "Configure");
        } catch (Exception ex) {
            // write a message or ignore
        }
    }

    private void listFactoryConfigurations(PrintWriter printWriter, ConfigurationAdmin configAdmin,
            String pidFilter, String localeInfo) {
        try {
            SortedMap optionsFactory = getServices(ManagedServiceFactory.class.getName(), pidFilter, localeInfo,
                    true);
            printOptionsForm(printWriter, optionsFactory, "configSelection_factory", "create", "Create");
        } catch (Exception ex) {
            // write a message or ignore
        }
    }

    private Dictionary mergeWithMetaType(Dictionary propsDictionary, ObjectClassDefinition classDef,
            JSONWriter jsonWriter) throws JSONException {

        if (propsDictionary == null) {
            propsDictionary = new Hashtable();
        }

        if (classDef != null) {

            jsonWriter.key("title");
            jsonWriter.value(classDef.getName());

            if (classDef.getDescription() != null) {
                jsonWriter.key("description");
                jsonWriter.value(classDef.getDescription());
            }

            AttributeDefinition[] currAttrDef = classDef.getAttributeDefinitions(ObjectClassDefinition.ALL);
            if (currAttrDef != null) {

                JSONArray propertyList = new JSONArray();

                for (int i = 0; i < currAttrDef.length; i++) {
                    jsonWriter.key(currAttrDef[i].getID());
                    jsonWriter.object();

                    Object idValue = propsDictionary.get(currAttrDef[i].getID());
                    if (idValue == null) {
                        idValue = currAttrDef[i].getDefaultValue();
                        if (idValue == null) {
                            if (currAttrDef[i].getCardinality() == 0) {
                                idValue = "";
                            } else {
                                idValue = new String[0];
                            }
                        }
                    }

                    jsonWriter.key("name");
                    jsonWriter.value(currAttrDef[i].getName());

                    jsonWriter.key("type");
                    if (currAttrDef[i].getOptionLabels() != null && currAttrDef[i].getOptionLabels().length > 0) {
                        jsonWriter.object();
                        jsonWriter.key("labels");
                        jsonWriter.value(Arrays.asList(currAttrDef[i].getOptionLabels()));
                        jsonWriter.key("values");
                        jsonWriter.value(Arrays.asList(currAttrDef[i].getOptionValues()));
                        jsonWriter.endObject();
                    } else {
                        jsonWriter.value(currAttrDef[i].getType());
                    }

                    if (currAttrDef[i].getCardinality() == 0) {
                        // scalar
                        if (idValue instanceof Vector) {
                            idValue = ((Vector) idValue).get(0);
                        } else if (idValue.getClass().isArray()) {
                            idValue = Array.get(idValue, 0);
                        }
                        jsonWriter.key("value");
                        jsonWriter.value(idValue);
                    } else {
                        if (idValue instanceof Vector) {
                            idValue = new JSONArray((Vector) idValue);
                        } else if (idValue.getClass().isArray()) {
                            idValue = new JSONArray(Arrays.asList((Object[]) idValue));
                        } else {
                            JSONArray tmp = new JSONArray();
                            tmp.put(idValue);
                            idValue = tmp;
                        }
                        jsonWriter.key("values");
                        jsonWriter.value(idValue);
                    }

                    if (currAttrDef[i].getDescription() != null) {
                        jsonWriter.key("description");
                        jsonWriter.value(currAttrDef[i].getDescription());
                    }

                    jsonWriter.endObject();
                    propertyList.put(currAttrDef[i].getID());
                }

                jsonWriter.key("propertylist");
                jsonWriter.value(propertyList);
            }

            // nothing more to display
            propsDictionary = null;
        }

        return propsDictionary;
    }

    private void printJsonConfig(PrintWriter printWriter, String pid, Configuration config, String pidFilter,
            String localeInfo) {

        JSONWriter jsonWriter = new JSONWriter(printWriter);

        if (pid != null) {
            try {
                jsonWriter.object();
                this.configForm(jsonWriter, pid, config, pidFilter, localeInfo);
                jsonWriter.endObject();
            } catch (Exception ex) {
                // add message
            }
        }

    }

    private void printOptionsForm(PrintWriter printWriter, SortedMap inputOptions, String formId,
            String submitMethod, String submitLabel) {
        SortedSet tempSet = new TreeSet();
        for (Iterator entryIter = inputOptions.entrySet().iterator(); entryIter.hasNext();) {
            Entry tempEntry = (Entry) entryIter.next();
            tempSet.add(tempEntry.getValue().toString() + Character.MAX_VALUE + tempEntry.getKey().toString());
        }

        printWriter.println(
                "<select class='select' name='pid' id='" + formId + "' onChange='" + submitMethod + "();'>");
        for (Iterator treeIter = tempSet.iterator(); treeIter.hasNext();) {
            String nextEntry = (String) treeIter.next();
            int specChar = nextEntry.indexOf(Character.MAX_VALUE);
            String partialEntry = nextEntry.substring(0, specChar);
            String entryKey = nextEntry.substring(specChar + STRING_FORWARD);
            printWriter.print("<option value='" + entryKey + "'>");
            printWriter.print(partialEntry);
            printWriter.println("</option>");
        }
        printWriter.println("</select>");
        printWriter.println("&nbsp;&nbsp;");
        printWriter.println("<input class='submit' type='button' value='" + submitLabel + "' onClick='"
                + submitMethod + "();' />");

    }

    /**
     * @see org.apache.felix.webconsole.AbstractWebConsolePluginServlet#renderServletRequest(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    public void renderServletRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // extract the configuration pid from the request path
        String tempPid = request.getPathInfo().substring(this.getServletLabel().length() + 1);
        if (tempPid.length() == 0) {
            tempPid = null;
        } else {
            tempPid = tempPid.substring(tempPid.lastIndexOf('/') + STRING_FORWARD);
        }
        // same procedure in doGet
        String currPidFilter = request.getParameter(PID_FILTER);
        if (currPidFilter == null) {
            currPidFilter = tempPid;
        }
        if (currPidFilter != null) {
            try {
                getBundleContext().createFilter(currPidFilter);

                // if the pidFilter was set from the pid, clear the pid
                if (tempPid == currPidFilter) {
                    tempPid = null;
                }
            } catch (InvalidSyntaxException ex) {
                // its ok, if the pid is just a single PID
                currPidFilter = null;
            }
        }

        final ConfigurationAdmin currConfigAdmin = this.getConfigurationAdmin();

        final Locale tempLocale = getLocale(request);
        final String localeInfo = (tempLocale != null) ? tempLocale.toString() : null;

        final PrintWriter printWriter = response.getWriter();

        final String attrAppRoot = (String) request.getAttribute(OsgiManager.OSGI_APP_ROOT);
        printWriter.println(
                "<script src='" + attrAppRoot + "/res/ui/configmanager.js' language='JavaScript'></script>");

        printWriter.println("<table class='content' cellpadding='0' cellspacing='0' width='100%'>");

        if (currConfigAdmin == null) {
            printWriter.println("<tr class='content' id='configField'>");
            printWriter.println("<td class='content'>&nbsp;</th>");
            printWriter.println("<td class='content'>");
            printWriter.print("Configuration Admin Service not available");
        } else {
            printWriter.println("<tr class='content' id='configField'>");
            printWriter.println("<td class='content'>Configurations</th>");
            printWriter.println("<td class='content'>");
            this.listConfigurations(printWriter, currConfigAdmin, currPidFilter, localeInfo);
            printWriter.println("</td>");
            printWriter.println("</tr>");

            printWriter.println("<tr class='content' id='factoryField'>");
            printWriter.println("<td class='content'>Factory Configurations</th>");
            printWriter.println("<td class='content'>");
            this.listFactoryConfigurations(printWriter, currConfigAdmin, currPidFilter, localeInfo);

        }
        printWriter.println("</td>");
        printWriter.println("</tr>");
        printWriter.println("</table>");

        // if a configuration is addressed, display it immediately
        final Configuration currConfig;
        if (request.getParameter("create") != null && tempPid != null) {
            currConfig = new PlaceholderConfiguration(tempPid);
            tempPid = currConfig.getPid();
        } else {
            currConfig = getConfigurationWithPid(currConfigAdmin, tempPid);
        }

        if (tempPid != null) {
            Util.startScript(printWriter);

            printWriter.println("var configuration=");
            printJsonConfig(printWriter, tempPid, currConfig, currPidFilter, localeInfo);

            printWriter.println(";");
            printWriter.println("displayConfigForm(configuration);");
            Util.endScript(printWriter);
        }
    }

}