laks.it
laks.it

Reputation: 165

CQ5 multifield configuration service

I'm trying to create a CQ5 service with a multifield configuration interface. It would be something like this but at the click of PLUS button it would add not just a new row but a group of N rows.

Property

  • Field1 +-
  • Field2
  • ....
  • FieldN

Any advice?

Upvotes: 0

Views: 602

Answers (2)

Poornima Jagadish
Poornima Jagadish

Reputation: 1

This is one way of doing it.

@Component(label = "My Service", metatype = true, immediate = true)
@Service(MyService.class)
@Properties({
    @Property(name = "my.property", description = "Provide details Eg: url=http://www.google.com|size=10|path=/content/project", value = "", unbounded = PropertyUnbounded.ARRAY) })

public class MyService {

private String[] myPropertyDetails;

@Activate
protected void activate(ComponentContext ctx) {
    this.myPropertyDetails = getPropertyAsArray(ctx.getProperties().get("my.property"));
    try {
        if (null != myPropertyDetails && myPropertyDetails.length > 0) {
            for(String myPropertyDetail : myPropertyDetails) {
                Map<String, String> map = new HashMap<String, String>();
                String[] propertyDetails = myPropertyDetails.split("|");
                for (String keyValuePair : propertyDetails) {
                    String[] keyValue = keyValuePair.split("=");
                    if (null != keyValue && keyValue.length > 1) {
                        map.put(keyValue[0], keyValue[1]);
                    }
                }                   
                /* the map now has all the properties in the form of key value pairs for single field 
                    use this for logic execution. when there are no multiple properties in the row, 
                    you can skip the  logic to split and add in the map */
            }
        }
    } catch (Exception e) {
        log.error( "Exception ", e.getMessage());
    }
}

private String[] getPropertyAsArray(Object obj) {
    String[] paths = { "" };
    if (obj != null) {
        if (obj instanceof String[]) {
            paths = (String[]) obj;
        } else {
            paths = new String[1];
            paths[0] = (String) obj;
        }
    }
    return paths;
}

}

Upvotes: 0

Mateusz Chromiński
Mateusz Chromiński

Reputation: 2832

As far as I know there is no such possibility in the Apache Felix.

Depending on your actual requirement I would consider decomposing the configuration. Try moving all the fieldsets (groups of fields that you'd like to add through the plus button) into a separated configuration. So, closely to the slf4j.Logger configuration you would have a Configuration Factory approach.

A simple configuration factory can look like following

@Component(immediate = true, configurationFactory = true, metatype = true, policy = ConfigurationPolicy.OPTIONAL, name = "com.foo.bar.MyConfigurationProvider", label = "Multiple Configuration Provider")
@Service(serviceFactory = false, value = { MyConfigurationProvider.class })
@Properties({
        @Property(name = "propertyA", label = "Value for property A"),
        @Property(name = "propertyB", label = "Value for property B") })
public class MyConfigurationProvider {

    private String propertyA;
    private String propertyB;

    @Activate
    protected void activate(final Map<String, Object> properties, final ComponentContext componentContext) {
        propertyA = PropertiesUtil.toStringArray(properties.get("propertyA"), defaultValue);
        propertyB = PropertiesUtil.toStringArray(properties.get("propertyB"), defaultValue);
    }
}

Using it is as simple as adding a reference in any @Component

@Reference(cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, referenceInterface = MyConfigurationProvider.class, policy = ReferencePolicy.DYNAMIC)
private final List<MyConfigurationProvider> providers = new LinkedList<MyConfigurationProvider>();

protected void bindProviders(MyConfigurationProvider provider) {
    providers.add(provider);
}

protected void unbindProviders(MyConfigurationProvider provider) {
    providers.remove(provider);
}

Upvotes: 1

Related Questions