FELIX-4710 : Web Console: Display templated name hint for factory configuration entries. Apply patch from Stefan Seifert
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1648330 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java
index 043ca44..f8bc2e5 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java
@@ -25,11 +25,13 @@
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
@@ -59,6 +61,12 @@
class ConfigAdminSupport
{
+
+ private static final String PROPERTY_FACTORYCONFIG_NAMEHINT = "webconsole.configurationFactory.nameHint";
+ private static final Set CONFIG_PROPERTIES_HIDE = new HashSet();
+ static {
+ CONFIG_PROPERTIES_HIDE.add(PROPERTY_FACTORYCONFIG_NAMEHINT);
+ }
private final BundleContext bundleContext;
private final ConfigurationAdmin service;
@@ -368,7 +376,7 @@
}
if ( ocd != null )
{
- mtss.mergeWithMetaType( props, ocd, json );
+ mtss.mergeWithMetaType( props, ocd, json, CONFIG_PROPERTIES_HIDE );
doSimpleMerge = false;
}
}
@@ -566,6 +574,7 @@
if ( null != fpid )
{
data.put( "fpid", fpid ); //$NON-NLS-1$
+ data.putOpt( "nameHint", getConfigurationFactoryNameHint(config, mtss) ); //$NON-NLS-1$
}
final Bundle bundle = getBoundBundle( config );
@@ -584,7 +593,93 @@
configManager.log("listConfigurations: Unexpected problem encountered", e);
}
}
+
+ /**
+ * Builds a "name hint" for factory configuration based on other property
+ * values of the config and a "name hint template" defined as hidden
+ * property in the service.
+ * @param props Service properties.
+ * @return Name hint or null if none is defined.
+ */
+ private static final String getConfigurationFactoryNameHint(Configuration config, MetaTypeServiceSupport mtss)
+ {
+ // check for configured name hint template
+ Dictionary props = config.getProperties();
+ Object nameHintTemplateObject = props.get(PROPERTY_FACTORYCONFIG_NAMEHINT);
+ if (nameHintTemplateObject == null || !(nameHintTemplateObject instanceof String))
+ {
+ // check for metatype default value for name hint template
+ if (mtss != null)
+ {
+ Map adMap = mtss.getAttributeDefinitionMap(config, null);
+ PropertyDescriptor ad = (PropertyDescriptor)adMap.get(PROPERTY_FACTORYCONFIG_NAMEHINT);
+ if (ad != null && ad.getDefaultValue() != null && ad.getDefaultValue().length == 1)
+ {
+ nameHintTemplateObject = ad.getDefaultValue()[0];
+ }
+ }
+ if (nameHintTemplateObject == null)
+ {
+ return null;
+ }
+ }
+ String nameHint = (String) nameHintTemplateObject;
+ Enumeration keys = props.keys();
+ while (keys.hasMoreElements())
+ {
+ String key = (String) keys.nextElement();
+ Object value = props.get(key);
+ if (value != null)
+ {
+ StringBuffer valueString = new StringBuffer();
+ if (value instanceof String[]) {
+ String[] valueArray = (String[])value;
+ for (int i = 0; i < valueArray.length; i++) {
+ if (i > 0) {
+ valueString.append(",");
+ }
+ valueString.append(valueArray[i]);
+ }
+ }
+ else {
+ valueString.append(value.toString());
+ }
+ nameHint = nameHint.replaceAll(regexQuote("{" + key + "}"), valueString.toString());
+ }
+ }
+ return nameHint;
+ }
+ /**
+ * Replacement for Pattern.quote(), which only available in JDK 1.5 and up.
+ * @param str Unquoted string
+ * @return Quoted string
+ */
+ private static final String regexQuote(String str)
+ {
+ int eInd = str.indexOf("\\E");
+ if (eInd < 0)
+ {
+ // No need to handle backslashes.
+ return "\\Q" + str + "\\E";
+ }
+
+ StringBuffer sb = new StringBuffer(str.length() + 16);
+ sb.append("\\Q"); // start quote
+
+ int pos = 0;
+ do
+ {
+ // A backslash is quoted by another backslash;
+ // 'E' is not needed to be quoted.
+ sb.append(str.substring(pos, eInd)).append("\\E" + "\\\\" + "E" + "\\Q");
+ pos = eInd + 2;
+ }
+ while ((eInd = str.indexOf("\\E", pos)) >= 0);
+
+ sb.append(str.substring(pos, str.length())).append("\\E"); // end quote
+ return sb.toString();
+ }
final void listFactoryConfigurations(JSONObject json, String pidFilter,
String locale)
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java
index 149c256..62341ee 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java
@@ -23,6 +23,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.json.JSONException;
import org.json.JSONWriter;
@@ -261,7 +262,7 @@
}
- void mergeWithMetaType( Dictionary props, ObjectClassDefinition ocd, JSONWriter json ) throws JSONException
+ void mergeWithMetaType( Dictionary props, ObjectClassDefinition ocd, JSONWriter json, Set ignoreAttrIds ) throws JSONException
{
json.key( "title" ).value( ocd.getName() ); //$NON-NLS-1$
@@ -280,9 +281,11 @@
{
final AttributeDefinition adi = ad[i];
final String attrId = adi.getID();
- json.key( attrId );
- boolean isOptional = optional.contains( adi );
- attributeToJson( json, new MetatypePropertyDescriptor( adi, isOptional ), props.get( attrId ) );
+ if (!ignoreAttrIds.contains(attrId)) {
+ json.key( attrId );
+ boolean isOptional = optional.contains( adi );
+ attributeToJson( json, new MetatypePropertyDescriptor( adi, isOptional ), props.get( attrId ) );
+ }
}
json.endObject();
}
diff --git a/webconsole/src/main/resources/res/ui/config.js b/webconsole/src/main/resources/res/ui/config.js
index 292d118..70e5026 100644
--- a/webconsole/src/main/resources/res/ui/config.js
+++ b/webconsole/src/main/resources/res/ui/config.js
@@ -468,7 +468,11 @@
// rendering name - indented if factory pid is set
var nms = tr.find('td:eq(1) div');
if (conf.fpid) {
- nms.after(conf.id);
+ if (conf.nameHint) {
+ nms.after("<span title='" + conf.id + "'>" + conf.nameHint + "</span>");
+ } else {
+ nms.after(conf.id);
+ }
tr.attr('fpid', conf.name);
} else {
nms.addClass('ui-helper-hidden').parent().text(conf.name);