All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.karaf.features.internal.region.OfflineResolver Maven / Gradle / Ivy

There is a newer version: 4.4.6
Show newest version
/*
 * 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.karaf.features.internal.region;

import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.felix.resolver.Logger;
import org.apache.felix.resolver.ResolverImpl;
import org.apache.felix.utils.repository.BaseRepository;
import org.apache.felix.utils.resource.RequirementImpl;
import org.apache.felix.utils.resource.ResourceBuilder;
import org.apache.felix.utils.resource.ResourceImpl;
import org.apache.felix.utils.resource.SimpleFilter;
import org.apache.karaf.util.json.JsonReader;
import org.osgi.framework.BundleException;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
import org.osgi.resource.Wiring;
import org.osgi.service.repository.Repository;
import org.osgi.service.resolver.HostedCapability;
import org.osgi.service.resolver.ResolveContext;
import org.osgi.service.resolver.Resolver;

import static org.osgi.framework.Constants.RESOLUTION_DIRECTIVE;
import static org.osgi.framework.Constants.RESOLUTION_OPTIONAL;
import static org.osgi.framework.namespace.IdentityNamespace.IDENTITY_NAMESPACE;

public class OfflineResolver {

    public static void main(String[] args) throws Exception {
        if (args == null || args.length != 1) {
            throw new IllegalArgumentException("File path expected");
        }
        resolve(args[0]);
    }

    public static void resolve(String resolutionFile) throws Exception {
        Map resolution;
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(resolutionFile), StandardCharsets.UTF_8)) {
            resolution = (Map) JsonReader.read(reader);
        }

        final Repository globalRepository;
        if (resolution.containsKey("globalRepository")) {
            globalRepository = readRepository(resolution.get("globalRepository"));
        } else {
            globalRepository = null;
        }
        final Repository repository = readRepository(resolution.get("repository"));

        Resolver resolver = new ResolverImpl(new Logger(Logger.LOG_ERROR));
        Map> wiring = resolver.resolve(new ResolveContext() {
            private final CandidateComparator candidateComparator = new CandidateComparator(r -> 0);

            @Override
            public Collection getMandatoryResources() {
                List resources = new ArrayList<>();
                Requirement req = new RequirementImpl(
                        null,
                        IDENTITY_NAMESPACE,
                        Collections.emptyMap(),
                        Collections.emptyMap(),
                        SimpleFilter.parse("(" + IDENTITY_NAMESPACE + "=root)"));
                Collection identities = repository.findProviders(Collections.singleton(req)).get(req);
                for (Capability identity : identities) {
                    resources.add(identity.getResource());
                }
                return resources;
            }

            @Override
            public List findProviders(Requirement requirement) {
                List caps = new ArrayList<>();
                Map> resMap =
                        repository.findProviders(Collections.singleton(requirement));
                Collection res = resMap != null ? resMap.get(requirement) : null;
                if (res != null && !res.isEmpty()) {
                    caps.addAll(res);
                } else if (globalRepository != null) {
                    // Only bring in external resources for non optional requirements
                    if (!RESOLUTION_OPTIONAL.equals(requirement.getDirectives().get(RESOLUTION_DIRECTIVE))) {
                        resMap = globalRepository.findProviders(Collections.singleton(requirement));
                        res = resMap != null ? resMap.get(requirement) : null;
                        if (res != null && !res.isEmpty()) {
                            caps.addAll(res);
                        }
                    }
                }

                // Sort caps
                caps.sort(candidateComparator);
                return caps;
            }

            @Override
            public int insertHostedCapability(List capabilities, HostedCapability hostedCapability) {
                int idx = Collections.binarySearch(capabilities, hostedCapability, candidateComparator);
                if (idx < 0) {
                    idx = Math.abs(idx + 1);
                }
                capabilities.add(idx, hostedCapability);
                return idx;
            }

            @Override
            public boolean isEffective(Requirement requirement) {
                return true;
            }

            @Override
            public Map getWirings() {
                return Collections.emptyMap();
            }
        });
    }

    private static Repository readRepository(Object repository) throws BundleException {
        List resources = new ArrayList<>();
        Collection>> metadatas;
        if (repository instanceof Map) {
            metadatas = ((Map>>) repository).values();
        } else {
            metadatas = (Collection>>) repository;
        }
        for (Map> metadata : metadatas) {
            ResourceImpl res = new ResourceImpl();
            for (String cap : metadata.get("capabilities")) {
                res.addCapabilities(ResourceBuilder.parseCapability(res, cap));
            }
            if (metadata.containsKey("requirements")) {
                for (String req : metadata.get("requirements")) {
                    res.addRequirements(ResourceBuilder.parseRequirement(res, req));
                }
            }
            resources.add(res);
        }
        return new BaseRepository(resources);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy