Package org.apache.sling.replication.resources.impl

Source Code of org.apache.sling.replication.resources.impl.OsgiConfigurationResourceProvider

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.replication.resources.impl;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.replication.resources.impl.common.AbstractModifyingResourceProvider;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;

/**
* {@link ResourceProvider} for Osgi configurations for a specific configuration factory.
* All CRUD operations are supported for the underlying resources.
* The accepted path is resourceRoot/{friendlyNameProperty}/childResourceName.
*/
public class OsgiConfigurationResourceProvider extends AbstractModifyingResourceProvider implements ResourceProvider, ModifyingResourceProvider {

    private final ConfigurationAdmin configurationAdmin;
    private final String configFactory;
    private final String friendlyNameProperty;

    public OsgiConfigurationResourceProvider(ConfigurationAdmin configurationAdmin,
                                             String configFactory,
                                             String friendlyNameProperty,
                                             String resourceRoot,
                                             Map<String, String> additionalResourceProperties) {
        super(resourceRoot, additionalResourceProperties);

        this.configurationAdmin = configurationAdmin;
        this.configFactory = configFactory;
        this.friendlyNameProperty = friendlyNameProperty;
    }

    @Override
    protected void save(ResourceResolver resourceResolver, Map<String, Map<String, Object>> changedResources,
                        Set<String> deletedResources) throws PersistenceException {
        try {
            for (Map.Entry<String, Map<String, Object>> entry : changedResources.entrySet()) {
                String resourceName = entry.getKey();
                Map<String, Object> properties = entry.getValue();

                String configName = getConfigName(resourceName);
                properties.put(friendlyNameProperty, configName);

                Configuration configuration = getConfiguration(configName);

                if (configuration == null) {
                    configuration = configurationAdmin.createFactoryConfiguration(configFactory);
                }

                properties = filterBeforeSave(properties);
                configuration.update(toDictionary(properties));
            }

            for (String resourceName : deletedResources) {
                String configName = getConfigName(resourceName);
                Configuration configuration = getConfiguration(configName);
                if (configuration != null) {
                    configuration.delete();
                }
            }
        } catch (IOException e) {
            throw new PersistenceException("Resources cannot be commited", e);
        }
    }

    @Override
    protected Map<String, Object> getResourceRootProperties() {
        Configuration[] configurations = getConfigurations(null);
        configurations = configurations == null ? new Configuration[0] : configurations;

        List<String> nameList = new ArrayList<String>();

        for (Configuration configuration : configurations) {
            String configName = (String) configuration.getProperties().get(friendlyNameProperty);

            if (configName != null) {
                nameList.add(configName);
            }
        }

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("items", nameList.toArray(new String[nameList.size()]));

        return result;
    }

    @Override
    protected Map<String, Object> getResourceProperties(String resourceName) {

        String configName = getConfigName(resourceName);
        Configuration configuration = getConfiguration(configName);


        if (configuration == null) {
            return null;
        }

        if (!configFactory.equals(configuration.getFactoryPid())) {
            return null;
        }


        Map<String, Object> properties = toMap(configuration);
        return filterBeforeRead(properties);
    }


    public Iterator<Resource> listChildren(Resource parent) {
        return null;
    }

    Configuration getConfiguration(String configName) {
        Configuration[] configurations = getConfigurations(configName);

        if (configurations == null || configurations.length != 1) {
            return null;
        }

        return configurations[0];
    }

    Configuration[] getConfigurations(String configName) {
        try {
            String filter = getFilter(configName);

            return configurationAdmin.listConfigurations(filter);
        } catch (IOException e) {
            return null;
        } catch (InvalidSyntaxException e) {
            return null;
        }
    }

    String getFilter(String configName) {
        if (configName != null) {
            return "(&(" + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + OsgiUtils.escape(configFactory) + ")("
                    + friendlyNameProperty + "=" + OsgiUtils.escape(configName) + "))";
        } else if (configFactory != null) {
            return "(" + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + OsgiUtils.escape(configFactory) + ")";
        }

        return null;
    }


    private Map<String, Object> toMap(Configuration configuration) {
        return fromDictionary(configuration.getProperties());
    }


    public static <K, V> Map<K, V> fromDictionary(Dictionary<K, V> dictionary) {
        if (dictionary == null) {
            return null;
        }
        Map<K, V> map = new HashMap<K, V>(dictionary.size());
        Enumeration<K> keys = dictionary.keys();
        while (keys.hasMoreElements()) {
            K key = keys.nextElement();
            map.put(key, dictionary.get(key));
        }
        return map;
    }

    public static <K, V> Dictionary<K, V> toDictionary(Map<K, V> map) {
        if (map == null) {
            return null;
        }
        Dictionary<K, V> dictionary = new Hashtable<K, V>(map.size());
        for (Map.Entry<K, V> entry : map.entrySet()) {
            dictionary.put(entry.getKey(), entry.getValue());
        }

        return dictionary;
    }

    private Map<String, Object> filterBeforeSave(Map<String, Object> properties) {
        Map<String, Object> result = new HashMap<String, Object>();

        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            if (entry.getKey().endsWith(".target")) {
                String entryValue = (String) entry.getValue();
                entryValue = packOsgiFilter(entryValue);
                if (entryValue != null) {
                    result.put(entry.getKey(), entryValue);
                }
            } else {
                result.put(entry.getKey(), entry.getValue());
            }

        }

        return result;

    }

    private Map<String, Object> filterBeforeRead(Map<String, Object> properties) {
        Map<String, Object> result = new HashMap<String, Object>();

        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            if (entry.getKey().endsWith(".target")) {
                String entryValue = (String) entry.getValue();
                entryValue = unpackOsgiFilter(entryValue);
                if (entryValue != null) {
                    result.put(entry.getKey(), entryValue);
                }
            } else {
                result.put(entry.getKey(), entry.getValue());
            }

        }

        return result;
    }


    private String unpackOsgiFilter(String propertyValue) {

        String result = null;

        String namePattern = "\\(" + friendlyNameProperty + "=(.*?)\\)";

        Pattern r = Pattern.compile(namePattern);
        Matcher m = r.matcher(propertyValue);

        if (m.matches()) {
            result = m.group(1);
        }

        return result;
    }

    private String packOsgiFilter(String propertyValue) {
        return "(" + friendlyNameProperty + "=" + OsgiUtils.escape(propertyValue) + ")";
    }

    private String getConfigName(String configName) {
        return configName;
    }
}
TOP

Related Classes of org.apache.sling.replication.resources.impl.OsgiConfigurationResourceProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.