FELIX-3282 Draw nice form also in the absence of MetaType information. The form setup is derived from current property values.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1215519 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
index 4e31674..8d79780 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
@@ -648,15 +648,21 @@
ocd = this.getObjectClassDefinition( pid, locale );
}
- props = this.mergeWithMetaType( props, ocd, json );
-
- if ( props != null )
+ if ( props == null )
{
+ props = new Hashtable();
+ }
+ if ( ocd != null )
+ {
+ this.mergeWithMetaType( props, ocd, json );
+ }
+ else
+ {
json.key( "title" ).value( pid );
- json.key( "description" ).value( "Please enter configuration properties for this configuration in the field below. This configuration has no associated description" );
-
- json.key( "propertylist" ).value( "properties" );
+ json.key( "description" )
+ .value(
+ "Please enter configuration properties for this configuration in the field below. This configuration has no associated description" );
json.key( "properties" ).object();
for ( Enumeration pe = props.keys(); pe.hasMoreElements(); )
@@ -665,16 +671,18 @@
// ignore well known special properties
if ( !key.equals( Constants.SERVICE_PID ) && !key.equals( Constants.SERVICE_DESCRIPTION )
- && !key.equals( Constants.SERVICE_ID ) && !key.equals( Constants.SERVICE_RANKING )
- && !key.equals( Constants.SERVICE_VENDOR )
+ && !key.equals( Constants.SERVICE_ID ) && !key.equals( Constants.SERVICE_VENDOR )
&& !key.equals( ConfigurationAdmin.SERVICE_BUNDLELOCATION )
&& !key.equals( ConfigurationAdmin.SERVICE_FACTORYPID ) )
{
- json.key( String.valueOf( key ) ).value( props.get( key ) );
+ final String id = ( String ) key;
+ final Object value = props.get( key );
+ final AttributeDefinition ad = getAttributeDefinition( id, value );
+ json.key( id );
+ attributeToJson( json, ad, value );
}
}
json.endObject();
-
}
if ( config != null )
@@ -684,50 +692,27 @@
}
- private Dictionary mergeWithMetaType( Dictionary props, ObjectClassDefinition ocd, JSONWriter json )
- throws JSONException
+ private void mergeWithMetaType( Dictionary props, ObjectClassDefinition ocd, JSONWriter json ) throws JSONException
{
+ json.key( "title" ).value( ocd.getName() );
- if ( props == null )
+ if ( ocd.getDescription() != null )
{
- props = new Hashtable();
+ json.key( "description" ).value( ocd.getDescription() );
}
- if ( ocd != null )
+ AttributeDefinition[] ad = ocd.getAttributeDefinitions( ObjectClassDefinition.ALL );
+ if ( ad != null )
{
-
- json.key( "title" );
- json.value( ocd.getName() );
-
- if ( ocd.getDescription() != null )
+ json.key( "properties" ).object();
+ for ( AttributeDefinition adi : ad )
{
- json.key( "description" );
- json.value( ocd.getDescription() );
+ final String attrId = adi.getID();
+ json.key( attrId );
+ attributeToJson( json, adi, props.get( attrId ) );
}
-
- AttributeDefinition[] ad = ocd.getAttributeDefinitions( ObjectClassDefinition.ALL );
- if ( ad != null )
- {
-
- JSONArray propertyList = new JSONArray();
-
- for ( AttributeDefinition adi : ad )
- {
- final String attrId = adi.getID();
- json.key( attrId );
- attributeToJson( json, adi, props.get( attrId ) );
- propertyList.put( attrId );
- }
-
- json.key( "propertylist" );
- json.value( propertyList );
- }
-
- // nothing more to display
- props = null;
+ json.endObject();
}
-
- return props;
}
@@ -820,18 +805,7 @@
String propertyList = request.getParameter( "propertylist" );
if ( propertyList == null )
{
- String propertiesString = request.getParameter( "properties" );
-
- if ( propertiesString != null )
- {
- byte[] propBytes = propertiesString.getBytes( "ISO-8859-1" );
- ByteArrayInputStream bin = new ByteArrayInputStream( propBytes );
- Properties props = new Properties();
- props.load( bin );
-
- config = getConfiguration( ca, pid, factoryPid );
- config.update( props );
- }
+ // FIXME: this would be a bug !!
}
else
{
@@ -844,86 +818,92 @@
}
Map adMap = this.getAttributeDefinitionMap( config, null );
- if ( adMap != null )
+ StringTokenizer propTokens = new StringTokenizer( propertyList, "," );
+ while ( propTokens.hasMoreTokens() )
{
- StringTokenizer propTokens = new StringTokenizer( propertyList, "," );
- while ( propTokens.hasMoreTokens() )
+ String propName = propTokens.nextToken();
+ AttributeDefinition ad = ( AttributeDefinition ) adMap.get( propName );
+
+ // try to derive from current value
+ if (ad == null) {
+ Object currentValue = props.get( propName );
+ ad = getAttributeDefinition( propName, currentValue );
+ }
+
+ int attributeType = getAttributeType( ad );
+
+ if ( ad == null
+ || ( ad.getCardinality() == 0 && ( attributeType == AttributeDefinition.STRING || attributeType == ATTRIBUTE_TYPE_PASSWORD ) ) )
{
- String propName = propTokens.nextToken();
- AttributeDefinition ad = ( AttributeDefinition ) adMap.get( propName );
- if ( ad == null
- || ( ad.getCardinality() == 0 && ( ad.getType() == AttributeDefinition.STRING || ad.getType() == ATTRIBUTE_TYPE_PASSWORD ) ) )
+ String prop = request.getParameter( propName );
+ if ( prop != null
+ && ( attributeType != ATTRIBUTE_TYPE_PASSWORD || !PASSWORD_PLACEHOLDER_VALUE.equals( prop ) ) )
{
- String prop = request.getParameter( propName );
- if ( prop != null
- && ( ad.getType() != ATTRIBUTE_TYPE_PASSWORD || !PASSWORD_PLACEHOLDER_VALUE.equals( prop ) ) )
+ props.put( propName, prop );
+ }
+ }
+ else if ( ad.getCardinality() == 0 )
+ {
+ // scalar of non-string
+ String prop = request.getParameter( propName );
+ if ( prop != null )
+ {
+ try
{
- props.put( propName, prop );
+ props.put( propName, toType( attributeType, prop ) );
+ }
+ catch ( NumberFormatException nfe )
+ {
+ // don't care
}
}
- else if ( ad.getCardinality() == 0 )
+ }
+ else
+ {
+ // array or vector of any type
+ Vector vec = new Vector();
+
+ String[] properties = request.getParameterValues( propName );
+ if ( properties != null )
{
- // scalar of non-string
- String prop = request.getParameter( propName );
- if ( prop != null )
+ if ( attributeType == ATTRIBUTE_TYPE_PASSWORD )
{
- try
- {
- props.put( propName, toType( ad.getType(), prop ) );
- }
- catch ( NumberFormatException nfe )
- {
- // don't care
- }
- }
- }
- else
- {
- // array or vector of any type
- Vector vec = new Vector();
-
- String[] properties = request.getParameterValues( propName );
- if ( properties != null )
- {
- if ( ad.getType() == ATTRIBUTE_TYPE_PASSWORD )
- {
- setPasswordProps( vec, properties, props.get( propName ) );
- }
- else
- {
- for ( int i = 0; i < properties.length; i++ )
- {
- try
- {
- vec.add( toType( ad.getType(), properties[i] ) );
- }
- catch ( NumberFormatException nfe )
- {
- // don't care
- }
- }
- }
- }
-
- // but ensure size (check for positive value since
- // abs(Integer.MIN_VALUE) is still INTEGER.MIN_VALUE)
- int maxSize = Math.abs( ad.getCardinality() );
- if ( vec.size() > maxSize && maxSize > 0 )
- {
- vec.setSize( maxSize );
- }
-
- if ( ad.getCardinality() < 0 )
- {
- // keep the vector
- props.put( propName, vec );
+ setPasswordProps( vec, properties, props.get( propName ) );
}
else
{
- // convert to an array
- props.put( propName, toArray( ad.getType(), vec ) );
+ for ( int i = 0; i < properties.length; i++ )
+ {
+ try
+ {
+ vec.add( toType( attributeType, properties[i] ) );
+ }
+ catch ( NumberFormatException nfe )
+ {
+ // don't care
+ }
+ }
}
}
+
+ // but ensure size (check for positive value since
+ // abs(Integer.MIN_VALUE) is still INTEGER.MIN_VALUE)
+ int maxSize = Math.abs( ad.getCardinality() );
+ if ( vec.size() > maxSize && maxSize > 0 )
+ {
+ vec.setSize( maxSize );
+ }
+
+ if ( ad.getCardinality() < 0 )
+ {
+ // keep the vector
+ props.put( propName, vec );
+ }
+ else
+ {
+ // convert to an array
+ props.put( propName, toArray( attributeType, vec ) );
+ }
}
}
@@ -1036,6 +1016,83 @@
json.endObject();
}
+
+ private static AttributeDefinition getAttributeDefinition( final String id, final Object value )
+ {
+ int attrType;
+ int attrCardinality;
+ Class type;
+
+ if ( value == null )
+ {
+ attrCardinality = 0;
+ type = String.class;
+ }
+ else if ( value instanceof Collection )
+ {
+ attrCardinality = Integer.MIN_VALUE;
+ Collection coll = ( Collection ) value;
+ if ( coll.isEmpty() )
+ {
+ type = String.class;
+ }
+ else
+ {
+ type = coll.iterator().next().getClass();
+ }
+ }
+ else if ( value.getClass().isArray() )
+ {
+ attrCardinality = Integer.MIN_VALUE;
+ type = value.getClass().getComponentType();
+ }
+ else
+ {
+ attrCardinality = 0;
+ type = value.getClass();
+ }
+
+ if ( type == Boolean.class || type == Boolean.TYPE )
+ {
+ attrType = AttributeDefinition.BOOLEAN;
+ }
+ else if ( type == Byte.class || type == Byte.TYPE )
+ {
+ attrType = AttributeDefinition.BYTE;
+ }
+ else if ( type == Character.class || type == Character.TYPE )
+ {
+ attrType = AttributeDefinition.CHARACTER;
+ }
+ else if ( type == Double.class || type == Double.TYPE )
+ {
+ attrType = AttributeDefinition.DOUBLE;
+ }
+ else if ( type == Float.class || type == Float.TYPE )
+ {
+ attrType = AttributeDefinition.FLOAT;
+ }
+ else if ( type == Long.class || type == Long.TYPE )
+ {
+ attrType = AttributeDefinition.LONG;
+ }
+ else if ( type == Integer.class || type == Integer.TYPE )
+ {
+ attrType = AttributeDefinition.INTEGER;
+ }
+ else if ( type == Short.class || type == Short.TYPE )
+ {
+ attrType = AttributeDefinition.SHORT;
+ }
+ else
+ {
+ attrType = AttributeDefinition.STRING;
+ }
+
+ return new PlaceholderAttributeDefinition( id, attrType, attrCardinality );
+ }
+
+
private static int getAttributeType( final AttributeDefinition ad )
{
if ( ad.getType() == AttributeDefinition.STRING && PASSWORD_PROPERTY.matcher( ad.getID() ).find() )
@@ -1239,5 +1296,75 @@
}
+ private static class PlaceholderAttributeDefinition implements AttributeDefinition
+ {
+ final String id;
+ final int type;
+ final int cardinality;
+
+
+ public PlaceholderAttributeDefinition( final String id, int type, int cardinality )
+ {
+ this.id = id;
+ this.type = type;
+ this.cardinality = cardinality;
+ }
+
+
+ public String getName()
+ {
+ return id;
+ }
+
+
+ public String getID()
+ {
+ return id;
+ }
+
+
+ public String getDescription()
+ {
+ // no description
+ return null;
+ }
+
+
+ public int getCardinality()
+ {
+ return cardinality;
+ }
+
+
+ public int getType()
+ {
+ return type;
+ }
+
+
+ public String[] getOptionValues()
+ {
+ return null;
+ }
+
+
+ public String[] getOptionLabels()
+ {
+ return null;
+ }
+
+
+ public String validate( String value )
+ {
+ // no validation
+ return null;
+ }
+
+
+ public String[] getDefaultValue()
+ {
+ return null;
+ }
+ }
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
index 525dd2e..99cbf8e 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
@@ -244,23 +244,20 @@
protected Map getAttributeDefinitionMap( Configuration config, String locale )
{
+ Map adMap = new HashMap();
ObjectClassDefinition ocd = this.getObjectClassDefinition( config, locale );
if ( ocd != null )
{
AttributeDefinition[] ad = ocd.getAttributeDefinitions( ObjectClassDefinition.ALL );
if ( ad != null )
{
- Map adMap = new HashMap();
for ( int i = 0; i < ad.length; i++ )
{
adMap.put( ad[i].getID(), ad[i] );
}
- return adMap;
}
}
-
- // fallback to nothing found
- return null;
+ return adMap;
}
diff --git a/webconsole/src/main/resources/res/ui/config.js b/webconsole/src/main/resources/res/ui/config.js
index eead16b..faa8e08 100644
--- a/webconsole/src/main/resources/res/ui/config.js
+++ b/webconsole/src/main/resources/res/ui/config.js
@@ -107,13 +107,9 @@
bodyEl.appendChild( trEl );
}
- if (obj.propertylist == 'properties')
+ if (obj.properties)
{
- printTextArea(bodyEl, obj.properties);
- }
- else
- {
- printForm(bodyEl, obj);
+ printForm(bodyEl, obj.properties);
}
printConfigurationInfo(parent, obj);
@@ -132,38 +128,11 @@
.dialog('open'));
}
-function printTextArea(/* Element */ parent, props )
-{
-
- var propsValue = "";
- for (var key in props)
- {
- propsValue += key + ' = ' + props[key] + '\r\n';
- }
-
- parent.appendChild(
- tr( null, null, [
- td( null, null, [
- text( i18n.props_title )
- ]),
- td( null, { style: { width: "99%" } }, [
- createElement( "textarea", null, {
- name: "properties",
- style: { height: "20em", width: "99%" }
- }, [ text( propsValue ) ] ),
- createElement( "br" ),
- text( i18n.props_enter )
- ])
- ])
- );
-}
-
-function printForm( /* Element */ parent, obj ) {
+function printForm( /* Element */ parent, /* Object */ properties ) {
var propList;
- for (var idx in obj.propertylist)
+ for (var prop in properties)
{
- var prop = obj.propertylist[idx];
- var attr = obj[prop];
+ var attr = properties[prop];
var trEl = tr( null, null, [
td( null, null, [ text( attr.name ) ] )
@@ -215,6 +184,7 @@
value: propList
})
);
+
// FIX for IE6 and above: checkbox can only be checked after it is in the DOM
$(".checked_box").attr("checked", true).removeClass("checked_box");
}