This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
The following commit(s) were added to refs/heads/master by this push:
new cc3b0125c2 FELIX-6531 : Web Console 4.8.0 does not generate metatype
configurations for services
cc3b0125c2 is described below
commit cc3b0125c20e9f8c2a8b0b2685d0aafa2eca02af
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Thu May 19 10:56:39 2022 +0200
FELIX-6531 : Web Console 4.8.0 does not generate metatype configurations
for services
---
.../internal/configuration/ConfigAdminSupport.java | 4 +-
.../internal/configuration/ConfigJsonSupport.java | 261 +++++++++++----------
.../configuration/MetaTypeServiceSupport.java | 63 -----
.../configuration/ConfigJsonSupportTest.java | 14 +-
4 files changed, 146 insertions(+), 196 deletions(-)
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 2840ce34d2..cf0ceaf2d8 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
@@ -93,12 +93,12 @@ class ConfigAdminSupport {
}
private Map<String, Object> getAllowedValues(final Configuration config,
final Dictionary<String, Object> props) throws IOException {
- final List<String> allowedProperties =
this.getJsonSupport().getPropertyNamesForForm(config.getFactoryPid(),
config.getPid(), props);
+
this.getJsonSupport().filterConfigurationProperties(config.getFactoryPid(),
config.getPid(), props);
final Map<String, Object> allowedValues = new HashMap<>();
final Dictionary<String, Object> origProps = config.getProperties();
if ( origProps != null ) {
for(final String name : Collections.list(origProps.keys())) {
- if ( !allowedProperties.contains(name) ) {
+ if ( props.get(name) == null ) {
allowedValues.put(name, origProps.get(name));
}
}
diff --git
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupport.java
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupport.java
index 323ac13e0b..767aaeface 100644
---
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupport.java
+++
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupport.java
@@ -24,14 +24,17 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
+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.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -93,13 +96,12 @@ class ConfigJsonSupport {
}
/**
- * Get the list of property names for the form and filter the properties
based on this list
+ * Filter the configuration properties
*/
- List<String> getPropertyNamesForForm(final String factoryPid, final String
pid,
- final Dictionary<String, Object> props)
+ void filterConfigurationProperties(final String factoryPid, final String
pid, final Dictionary<String, Object> props)
throws IOException {
- final List<String> names = new
ArrayList<>(Collections.list(props.keys()));
- if ( !configurationHandlers.isEmpty() && !names.isEmpty()) {
+ if ( props != null && !configurationHandlers.isEmpty() &&
!props.isEmpty()) {
+ final List<String> names = new
ArrayList<>(Collections.list(props.keys()));
// fill remove list with all names
final List<String> removeList = new ArrayList<>(names);
for(final ConfigurationHandler handler : configurationHandlers) {
@@ -110,9 +112,45 @@ class ConfigJsonSupport {
// remove properties
removeList.forEach(props::remove);
}
- return names;
}
+ /**
+ * Filter the attribute definitions
+ */
+ List<AttributeDefinition> filterAttributeDefinitions(final String
factoryPid, final String pid, final AttributeDefinition[] ads)
+ throws IOException {
+ final List<AttributeDefinition> result = new ArrayList<>();
+ if ( ads != null && ads.length > 0 ) {
+ final List<String> names = new ArrayList<>();
+ for(final AttributeDefinition ad : ads) {
+ names.add(ad.getID());
+ }
+ for(final ConfigurationHandler handler : configurationHandlers) {
+ handler.filterProperties(factoryPid, pid, names);
+ }
+ for(final AttributeDefinition ad : ads) {
+ if ( names.contains(ad.getID())) {
+ result.add(ad);
+ }
+ }
+ }
+ return result;
+ }
+
+ ObjectClassDefinition getObjectClassDefinition( Configuration config,
String pid, String locale ) {
+ ObjectClassDefinition ocd = null;
+ if ( this.mtss != null ) {
+ if ( config != null ) {
+ ocd = this.mtss.getObjectClassDefinition( config, locale );
+ }
+ if ( ocd == null ) {
+ ocd = this.mtss.getObjectClassDefinition( pid, locale );
+ }
+ }
+ return ocd;
+ }
+
+
void configForm( final JSONWriter json, final String pid, final
Configuration config, final String pidFilter, final String locale )
throws IOException {
json.key( ConfigManager.PID );
@@ -123,89 +161,72 @@ class ConfigJsonSupport {
json.value( pidFilter );
}
- Dictionary<String, Object> props = null;
- if ( config != null ) {
- props = config.getProperties();
- }
- if ( props == null ) {
- props = new Hashtable<>();
- }
- final List<String> keys = getPropertyNamesForForm(config != null ?
config.getFactoryPid() : null, pid, props);
+ // get configuration properties and filter
+ final Dictionary<String, Object> props = config == null ? null :
config.getProperties();
+ filterConfigurationProperties(config != null ? config.getFactoryPid()
: null, pid, props);
- boolean doSimpleMerge = true;
- if ( this.mtss != null ) {
- ObjectClassDefinition ocd = null;
- if ( config != null ) {
- ocd = mtss.getObjectClassDefinition( config, locale );
- }
- if ( ocd == null ) {
- ocd = mtss.getObjectClassDefinition( pid, locale );
- }
- ObjectClassDefinition filteredOcd = ocd;
- if ( ocd != null ) {
- final ObjectClassDefinition focd = ocd;
- filteredOcd = new ObjectClassDefinition() {
- @Override
- public String getName() {
- return focd.getName();
- }
-
- @Override
- public String getID() {
- return focd.getID();
- }
+ final ObjectClassDefinition ocd =
this.getObjectClassDefinition(config, pid, locale);
+ if ( ocd != null ) {
+ json.key( "title" ).value( ocd.getName() ); //$NON-NLS-1$
- @Override
- public String getDescription() {
- return focd.getDescription();
- }
+ if ( ocd.getDescription() != null ) {
+ json.key( "description" ).value( ocd.getDescription() );
//$NON-NLS-1$
+ }
+
+ final AttributeDefinition[] optionalArray =
ocd.getAttributeDefinitions( ObjectClassDefinition.OPTIONAL );
+ final List<AttributeDefinition> optional = optionalArray == null ?
Collections.emptyList() : Arrays.asList( optionalArray );
+ final List<AttributeDefinition> attributes =
filterAttributeDefinitions(config != null ? config.getFactoryPid() : null, pid,
ocd.getAttributeDefinitions( ObjectClassDefinition.ALL ));
- @Override
- public AttributeDefinition[] getAttributeDefinitions(int
i) {
- AttributeDefinition[] allDefinitions =
focd.getAttributeDefinitions(i);
- if (allDefinitions != null) {
- ArrayList<AttributeDefinition> filteredDefinitions
= new ArrayList<>();
- for (AttributeDefinition def : allDefinitions) {
- if (keys.contains(def.getID())) {
- filteredDefinitions.add(def);
- }
- }
- return filteredDefinitions.toArray(new
AttributeDefinition[0]);
+ final Set<String> metatypeAttributes = new HashSet<>(
ConfigAdminSupport.CONFIG_PROPERTIES_HIDE );
+ json.key( "properties" ).object(); //$NON-NLS-1$
+ for(final AttributeDefinition adi : attributes) {
+ final String attrId = adi.getID();
+ if (!
ConfigAdminSupport.CONFIG_PROPERTIES_HIDE.contains(attrId)) {
+ json.key( attrId );
+ final boolean isOptional = optional.contains( adi );
+ MetaTypeServiceSupport.attributeToJson( json, new
MetatypePropertyDescriptor( adi, isOptional ), props == null ? null :
props.get( attrId ) );
+ }
+ metatypeAttributes.add( attrId );
+ }
+ json.endObject();
+ if ( props != null ) {
+ final StringBuffer sb = new StringBuffer();
+ for(final String key : Collections.list(props.keys())) {
+ if ( !metatypeAttributes.contains(key) ) {
+ if ( sb.length() > 0 ) {
+ sb.append(',');
}
- return null;
+ sb.append(key);
}
-
- @Override
- public InputStream getIcon(int i) throws IOException {
- return focd.getIcon(i);
- }
- };
- mtss.mergeWithMetaType( props, filteredOcd, json,
ConfigAdminSupport.CONFIG_PROPERTIES_HIDE );
- doSimpleMerge = false;
+ }
+ if ( sb.length() > 0 ) {
+ json.key("additionalProperties").value(sb.toString());
+ }
}
- }
- if (doSimpleMerge) {
+ } else {
json.key( "title" ).value( pid ); //$NON-NLS-1$
json.key( "description" ).value( //$NON-NLS-1$
"This form is automatically generated from existing
properties because no property "
- + "descriptors are available for this configuration. This
may be cause by the absence "
+ + "descriptors are available for this configuration. This
may be caused by the absence "
+ "of the OSGi Metatype Service or the absence of a
MetaType descriptor for this configuration." );
json.key( "properties" ).object(); //$NON-NLS-1$
- for ( Enumeration<String> pe = props.keys(); pe.hasMoreElements();
) {
- final String id = pe.nextElement();
-
- // ignore well known special properties
- if ( !id.equals( Constants.SERVICE_PID ) && !id.equals(
Constants.SERVICE_DESCRIPTION )
- && !id.equals( Constants.SERVICE_ID ) && !id.equals(
Constants.SERVICE_VENDOR )
- && !id.equals(
ConfigurationAdmin.SERVICE_BUNDLELOCATION )
- && !id.equals( ConfigurationAdmin.SERVICE_FACTORYPID )
) {
- final Object value = props.get( id );
- final PropertyDescriptor ad =
MetaTypeServiceSupport.createAttributeDefinition( id, value );
- json.key( id );
- MetaTypeServiceSupport.attributeToJson( json, ad, value );
- }
+ if ( props != null ) {
+ for ( Enumeration<String> pe = props.keys();
pe.hasMoreElements(); ) {
+ final String id = pe.nextElement();
+
+ // ignore well known special properties
+ if ( !id.equals( Constants.SERVICE_PID ) && !id.equals(
Constants.SERVICE_DESCRIPTION )
+ && !id.equals( Constants.SERVICE_ID ) &&
!id.equals( Constants.SERVICE_VENDOR )
+ && !id.equals(
ConfigurationAdmin.SERVICE_BUNDLELOCATION )
+ && !id.equals(
ConfigurationAdmin.SERVICE_FACTORYPID ) ) {
+ final Object value = props.get( id );
+ final PropertyDescriptor ad =
MetaTypeServiceSupport.createAttributeDefinition( id, value );
+ json.key( id );
+ MetaTypeServiceSupport.attributeToJson( json, ad,
value );
+ }
+ }
}
json.endObject();
}
@@ -342,46 +363,40 @@ class ConfigJsonSupport {
jw.key("pids");//$NON-NLS-1$
jw.array();
- for ( Iterator<String> ii = optionsPlain.keySet().iterator();
ii.hasNext(); )
- {
- hasConfigurations = true;
- String id = ii.next();
- Object name = optionsPlain.get( id );
-
- final Configuration c = ConfigurationUtil.findConfiguration(
this.configurationAdmin, id );
- Configuration config = c;
- if (null != config && !this.configurationHandlers.isEmpty()) {
- for(final ConfigurationHandler handler :
this.configurationHandlers) {
- if (!handler.listConfiguration(config.getFactoryPid(),
config.getPid())) {
- config = null;
- break;
- }
+ for ( final Map.Entry<String,String> entry :
optionsPlain.entrySet() ) {
+
+ final Configuration config =
ConfigurationUtil.findConfiguration( this.configurationAdmin, entry.getKey());
+ boolean include = true;
+ for(final ConfigurationHandler handler :
this.configurationHandlers) {
+ if (!handler.listConfiguration(config != null ?
config.getFactoryPid() : null, entry.getKey())) {
+ include = false;
+ break;
}
}
- if ( null != config )
- {
- jw.object();
- jw.key("id").value( id ); //$NON-NLS-1$
- jw.key( "name").value( name ); //$NON-NLS-1$
- // FELIX-3848
- jw.key("has_config").value( true ); //$NON-NLS-1$
-
- final String fpid = config.getFactoryPid();
- if ( null != fpid )
- {
- jw.key("fpid").value( fpid ); //$NON-NLS-1$
- final String val =
getConfigurationFactoryNameHint(config);
- if ( val != null )
- {
- jw.key( "nameHint").value(val ); //$NON-NLS-1$
+ if ( include ) {
+ hasConfigurations = true;
+ jw.object();
+ jw.key("id").value( entry.getKey() ); //$NON-NLS-1$
+ jw.key( "name").value( entry.getValue() ); //$NON-NLS-1$
+
+ if ( null != config ) {
+ // FELIX-3848
+ jw.key("has_config").value( true ); //$NON-NLS-1$
+
+ if ( config.getFactoryPid() != null ) {
+ jw.key("fpid").value( config.getFactoryPid() );
//$NON-NLS-1$
+ final String val =
getConfigurationFactoryNameHint(config);
+ if ( val != null ) {
+ jw.key( "nameHint").value(val ); //$NON-NLS-1$
+ }
}
- }
- final Bundle bundle = getBoundBundle( config );
- if ( null != bundle ) {
- jw.key( "bundle").value( bundle.getBundleId() );
//$NON-NLS-1$
- jw.key( "bundle_name").value( Util.getName( bundle,
loc ) ); //$NON-NLS-1$
+ final Bundle bundle = getBoundBundle( config );
+ if ( null != bundle ) {
+ jw.key( "bundle").value( bundle.getBundleId() );
//$NON-NLS-1$
+ jw.key( "bundle_name").value( Util.getName(
bundle, loc ) ); //$NON-NLS-1$
+ }
}
jw.endObject();
}
@@ -510,8 +525,7 @@ class ConfigJsonSupport {
return sb.toString();
}
- final void listFactoryConfigurations(JSONWriter jw, String pidFilter,
- String locale) {
+ final void listFactoryConfigurations(final JSONWriter jw, final String
pidFilter, final String locale) {
try {
final Map<String, String> optionsFactory =
getServices(ManagedServiceFactory.class.getName(),
pidFilter, locale, true);
@@ -521,13 +535,20 @@ class ConfigJsonSupport {
}
jw.key("fpids");
jw.array();
- for ( Iterator<String> ii = optionsFactory.keySet().iterator();
ii.hasNext(); ) {
- String id = ii.next();
- Object name = optionsFactory.get( id );
- jw.object();
- jw.key("id").value(id ); //$NON-NLS-1$
- jw.key("name").value( name ); //$NON-NLS-1$
- jw.endObject();
+ for ( final Map.Entry<String, String> entry :
optionsFactory.entrySet() ) {
+ boolean include = true;
+ for(final ConfigurationHandler handler :
this.configurationHandlers) {
+ if (!handler.listConfiguration(entry.getKey(),
entry.getKey())) {
+ include = false;
+ break;
+ }
+ }
+ if ( include ) {
+ jw.object();
+ jw.key("id").value( entry.getKey() ); //$NON-NLS-1$
+ jw.key("name").value( entry.getValue() ); //$NON-NLS-1$
+ jw.endObject();
+ }
}
jw.endArray();
} catch (final Exception e) {
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 f7318e1a4d..e6794abe37 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
@@ -17,18 +17,9 @@
package org.apache.felix.webconsole.internal.configuration;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
import java.util.Map;
-import java.util.Set;
-import org.apache.felix.utils.json.JSONWriter;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.Configuration;
@@ -158,7 +149,6 @@ class MetaTypeServiceSupport extends MetaTypeSupport
return objectClassesDefinitions;
}
-
ObjectClassDefinition getObjectClassDefinition( Configuration config,
String locale )
{
// if the configuration is bound, try to get the object class
@@ -263,59 +253,6 @@ class MetaTypeServiceSupport extends MetaTypeSupport
return adMap;
}
-
- void mergeWithMetaType( Dictionary<String, Object> props,
ObjectClassDefinition ocd, JSONWriter json, Set<String> ignoreAttrIds )
- throws IOException
- {
- json.key( "title" ).value( ocd.getName() ); //$NON-NLS-1$
-
- if ( ocd.getDescription() != null )
- {
- json.key( "description" ).value( ocd.getDescription() );
//$NON-NLS-1$
- }
-
- AttributeDefinition[] ad = ocd.getAttributeDefinitions(
ObjectClassDefinition.ALL );
- AttributeDefinition[] optionalArray = ocd.getAttributeDefinitions(
ObjectClassDefinition.OPTIONAL );
- List<AttributeDefinition>optional = optionalArray == null ?
Collections.emptyList() : Arrays.asList( optionalArray );
- final Set<String> metatypeAttributes = new HashSet<>(ignoreAttrIds);
- if ( ad != null )
- {
- json.key( "properties" ).object(); //$NON-NLS-1$
- for ( int i = 0; i < ad.length; i++ )
- {
- final AttributeDefinition adi = ad[i];
- final String attrId = adi.getID();
- if (!ignoreAttrIds.contains(attrId)) {
- json.key( attrId );
- boolean isOptional = optional.contains( adi );
- attributeToJson( json, new MetatypePropertyDescriptor(
adi, isOptional ), props.get( attrId ) );
- }
- metatypeAttributes.add( attrId );
- }
- json.endObject();
- }
- final StringBuffer sb = new StringBuffer();
- final Enumeration<String> e = props.keys();
- while ( e.hasMoreElements() )
- {
- String key = e.nextElement();
- if ( !metatypeAttributes.contains(key) ) {
- if ( sb.length() > 0 )
- {
- sb.append(',');
- }
- sb.append(key);
- }
- }
- if ( sb.length() > 0 )
- {
- json.key("additionalProperties").value(sb.toString());
- }
- }
-
-
-
-
/**
* The <code>IdGetter</code> interface is an internal helper to abstract
* retrieving object class definitions from all bundles for either
diff --git
a/webconsole/src/test/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupportTest.java
b/webconsole/src/test/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupportTest.java
index 8f992bbf18..a6f0dfe856 100644
---
a/webconsole/src/test/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupportTest.java
+++
b/webconsole/src/test/java/org/apache/felix/webconsole/internal/configuration/ConfigJsonSupportTest.java
@@ -41,10 +41,7 @@ public class ConfigJsonSupportTest {
dict.put("a", "1");
dict.put("b", "2");
- final List<String> names = support.getPropertyNamesForForm("f", "p",
dict);
- assertEquals(2, names.size());
- assertTrue(names.contains("a"));
- assertTrue(names.contains("b"));
+ support.filterConfigurationProperties("f", "p", dict);
assertEquals(2, dict.size());
assertEquals("1", dict.get("a"));
@@ -79,10 +76,7 @@ public class ConfigJsonSupportTest {
dict.put("a", "1");
dict.put("b", "2");
- final List<String> names = support.getPropertyNamesForForm("f", "p",
dict);
- assertEquals(2, names.size());
- assertTrue(names.contains("a"));
- assertTrue(names.contains("b"));
+ support.filterConfigurationProperties("f", "p", dict);
assertEquals(2, dict.size());
assertEquals("1", dict.get("a"));
@@ -124,9 +118,7 @@ public class ConfigJsonSupportTest {
dict.put("a", "1");
dict.put("b", "2");
- final List<String> names = support.getPropertyNamesForForm("f", "p",
dict);
- assertEquals(1, names.size());
- assertTrue(names.contains("a"));
+ support.filterConfigurationProperties("f", "p", dict);
assertEquals(1, dict.size());
assertEquals("1", dict.get("a"));