in webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java [118:307]
String applyConfiguration( final HttpServletRequest request, final String pid, final String[] propertyList, final boolean isUpdate )
throws ValidationException, IOException
{
final String factoryPid = request.getParameter( ConfigManager.FACTORY_PID );
final Configuration config = ConfigurationUtil.getOrCreateConfiguration( this.service, this.configurationHandlers, pid, factoryPid );
Dictionary<String, Object> props = config.getProperties();
if ( props == null ) {
props = new Hashtable<>();
}
// filter properties and keep filtered values
final Map<String, Object> allowedValues = getAllowedValues(config, props);
final MetaTypeServiceSupport mtss = getMetaTypeSupport();
final Map<String, MetatypePropertyDescriptor> adMap = ( mtss != null ) ? mtss.getAttributeDefinitionMap( config, null ) : new HashMap<>();
final List<String> propsToKeep = new ArrayList<>();
for(final String propName : propertyList)
{
final String paramName = "action".equals(propName)
|| ConfigManager.ACTION_DELETE.equals(propName)
|| ConfigManager.ACTION_APPLY.equals(propName)
|| ConfigManager.PROPERTY_LIST.equals(propName)
? '$' + propName : propName;
propsToKeep.add(propName);
PropertyDescriptor ad = adMap.get( propName );
// try to derive from current value
if (ad == null) {
Object currentValue = props.get( propName );
ad = MetaTypeSupport.createAttributeDefinition( propName, currentValue );
}
final int attributeType = MetaTypeSupport.getAttributeType( ad );
if ( ad.getCardinality() == 0 && ( attributeType == AttributeDefinition.STRING || attributeType == AttributeDefinition.PASSWORD ) )
{
final String value = request.getParameter( paramName );
if ( value != null
&& ( attributeType != AttributeDefinition.PASSWORD || !MetaTypeSupport.PASSWORD_PLACEHOLDER_VALUE.equals( value ) ) )
{
props.put( propName, value );
}
}
else if ( ad.getCardinality() == 0 )
{
// scalar of non-string
final String value = request.getParameter( paramName );
if ( value != null )
{
try
{
props.put( propName, MetaTypeSupport.toType( attributeType, value ) );
}
catch ( final NumberFormatException nfe )
{
// the value is put as a string, for example this could be a placeholder etc
props.put( propName, value);
}
}
}
else
{
// array or vector of any type
Vector<Object> vec = new Vector<>();
boolean formatError = false;
final String[] values = request.getParameterValues( paramName );
if ( values != null )
{
if ( attributeType == AttributeDefinition.PASSWORD )
{
MetaTypeSupport.setPasswordProps( vec, values, props.get( propName ) );
}
else
{
for ( int i = 0; i < values.length; i++ )
{
try
{
vec.add( MetaTypeSupport.toType( attributeType, values[i] ) );
}
catch ( NumberFormatException nfe )
{
// the value is put as a string, for example this could be a placeholder etc
vec.add( values[i] );
formatError = true;
}
}
}
}
// if a format error occurred revert to String!
if ( formatError )
{
Vector<Object> newVec = new Vector<Object>();
for(final Object v : vec)
{
newVec.add(v.toString());
}
vec = newVec;
}
// 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 );
}
// create array to compare
final String[] valueArray = new String[vec.size()];
for(int i=0; i<vec.size();i++)
{
valueArray[i] = vec.get(i).toString();
}
if ( ad.getCardinality() < 0 )
{
// keep the vector, but only add if not empty
if ( vec.isEmpty() )
{
props.remove( propName );
}
else
{
props.put( propName, vec );
}
}
else
{
// convert to an array
props.put( propName, MetaTypeSupport.toArray( formatError ? AttributeDefinition.STRING : attributeType, vec ) );
}
}
}
if ( !isUpdate )
{
// remove the properties that are not specified in the request
final Dictionary<String, Object> updateProps = new Hashtable<>(props.size());
for ( Enumeration<String> e = props.keys(); e.hasMoreElements(); )
{
final String key = e.nextElement();
if ( propsToKeep.contains(key) && props.get(key) != null )
{
updateProps.put(key, props.get(key));
}
}
props = updateProps;
}
// call update handlers
for(final ConfigurationHandler h : this.configurationHandlers) {
h.updateConfiguration(factoryPid, pid, props);
}
// reapply allowed values
for(final Map.Entry<String, Object> allowed : allowedValues.entrySet()) {
props.put(allowed.getKey(), allowed.getValue());
}
final String location = request.getParameter(ConfigManager.LOCATION);
if ( location == null || location.trim().length() == 0 || ConfigManager.UNBOUND_LOCATION.equals(location) )
{
if ( config.getBundleLocation() != null )
{
config.setBundleLocation(null);
// workaround for Felix Config Admin 1.2.8 not clearing dynamic
// bundle location when clearing static bundle location. In
// this case we first set the static bundle location to the
// dynamic bundle location and then try to set both to null
if ( config.getBundleLocation() != null )
{
config.setBundleLocation( "??invalid:bundle/location" );
config.setBundleLocation( null );
}
}
}
else
{
if ( config.getBundleLocation() == null || !config.getBundleLocation().equals(location) )
{
config.setBundleLocation(location);
}
}
config.update( props );
return config.getPid();
}