Package org.apache.felix.sigil.ivy

Source Code of org.apache.felix.sigil.ivy.ProjectRepository

/*
* 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.felix.sigil.ivy;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.felix.sigil.common.config.BldFactory;
import org.apache.felix.sigil.common.config.IBldProject;
import org.apache.felix.sigil.common.config.IBldProject.IBldBundle;
import org.apache.felix.sigil.common.core.licence.ILicensePolicy;
import org.apache.felix.sigil.common.model.ModelElementFactory;
import org.apache.felix.sigil.common.model.eclipse.ISigilBundle;
import org.apache.felix.sigil.common.model.osgi.IBundleModelElement;
import org.apache.felix.sigil.common.model.osgi.IPackageExport;
import org.apache.felix.sigil.common.model.osgi.IPackageImport;
import org.apache.felix.sigil.common.model.osgi.IRequiredBundle;
import org.apache.felix.sigil.common.osgi.VersionRange;
import org.apache.felix.sigil.common.osgi.VersionTable;
import org.apache.felix.sigil.common.repository.AbstractBundleRepository;
import org.apache.felix.sigil.common.repository.IRepositoryVisitor;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;

import org.osgi.framework.Version;

public class ProjectRepository extends AbstractBundleRepository
{
    private ArrayList<ISigilBundle> bundles;
    private ArrayList<ISigilBundle> wildBundles;
    private String projectFilePattern;

    /* package */ProjectRepository(String id, String projectFilePattern)
    {
        super(id);
        this.projectFilePattern = projectFilePattern.replaceAll("\\[sigilproject\\]",
            IBldProject.PROJECT_FILE);
    }

    @Override
    public void accept(IRepositoryVisitor visitor, int options)
    {
        for (ISigilBundle b : getBundles())
        {
            if (!visitor.visit(b))
            {
                break;
            }
        }
    }

    // override to provide fuzzy matching for wild-card exports.
    @Override
    public Collection<ISigilBundle> findAllProviders(final IPackageImport pi, int options)
    {
        return findProviders(pi, options, false);
    }

    @Override
    public ISigilBundle findProvider(IPackageImport pi, int options)
    {
        Collection<ISigilBundle> found = findProviders(pi, options, true);
        return found.isEmpty() ? null : found.iterator().next();
    }

    private Collection<ISigilBundle> findProviders(final IPackageImport pi, int options,
        boolean findFirst)
    {
        ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
        ILicensePolicy policy = findPolicy(pi);
        String name = pi.getPackageName();
        VersionRange versions = pi.getVersions();

        // find exact match(es)
        for (ISigilBundle bundle : getBundles())
        {
            if (policy.accept(bundle))
            {
                for (IPackageExport exp : bundle.getBundleInfo().getExports())
                {
                    if (name.equals(exp.getPackageName())
                        && versions.contains(exp.getVersion()))
                    {
                        found.add(bundle);
                        if (findFirst)
                            return found;
                    }
                }
            }
        }

        if (!found.isEmpty())
            return found;

        // find best fuzzy match
        ISigilBundle fuzzyMatch = null;
        int fuzzyLen = 0;

        for (ISigilBundle bundle : getWildBundles())
        {
            if (policy.accept(bundle))
            {
                for (IPackageExport exp : bundle.getBundleInfo().getExports())
                {
                    String export = exp.getPackageName();
                    if (export.endsWith("*"))
                    {
                        String export1 = export.substring(0, export.length() - 1);
                        if ((name.startsWith(export1) || export1.equals(name + "."))
                            && versions.contains(exp.getVersion()))
                        {
                            if (export1.length() > fuzzyLen)
                            {
                                fuzzyLen = export1.length();
                                fuzzyMatch = bundle;
                            }
                        }
                    }
                }
            }
        }

        if (fuzzyMatch != null)
            found.add(fuzzyMatch);

        return found;
    }

    private synchronized void init()
    {
        System.out.println("Sigil: loading Project Repository: " + projectFilePattern);

        ArrayList<File> projects = new ArrayList<File>();

        for (String pattern : projectFilePattern.split("\\s+"))
        {
            try
            {
                Collection<File> files = FindUtil.findFiles(new File(""), pattern);
                if (files.isEmpty())
                {
                    Log.warn("ProjectRepository: no projects match: " + pattern);
                }
                else
                {
                    projects.addAll(files);
                }
            }
            catch (IOException e)
            {
                // pattern root dir does not exist
                Log.error("ProjectRepository: " + pattern + ": " + e.getMessage());
            }
        }

        if (projects.isEmpty())
        {
            throw new IllegalArgumentException(
                "ProjectRepository: no projects found using pattern: "
                    + projectFilePattern + " pwd=" + new File("").getAbsolutePath());
        }

        bundles = new ArrayList<ISigilBundle>();

        for (File proj : projects)
        {
            try
            {
                addBundles(proj, bundles);
            }
            catch (IOException e)
            {
                Log.warn("Skipping project: " + proj + ": " + e.getMessage());
            }
            catch (ParseException e)
            {
                Log.warn("Skipping project: " + proj + ": " + e.getMessage());
            }
        }
    }

    private List<ISigilBundle> getBundles()
    {
        if (bundles == null)
        {
            init();
        }
        return bundles;
    }

    private List<ISigilBundle> getWildBundles()
    {
        if (wildBundles == null)
        {
            wildBundles = new ArrayList<ISigilBundle>();
            for (ISigilBundle bundle : getBundles())
            {
                for (IPackageExport exp : bundle.getBundleInfo().getExports())
                {
                    String export = exp.getPackageName();
                    if (export.endsWith("*"))
                    {
                        wildBundles.add(bundle);
                        break;
                    }
                }
            }
        }
        return wildBundles;
    }

    public void refresh()
    {
        bundles = null;
        wildBundles = null;
        notifyChange();
    }

    private void addBundles(File file, List<ISigilBundle> list) throws IOException,
        ParseException
    {
        URI uri = file.getCanonicalFile().toURI();
        IBldProject project = BldFactory.getProject(uri);

        for (IBldBundle bb : project.getBundles())
        {
            IBundleModelElement info = ModelElementFactory.getInstance().newModelElement(
                IBundleModelElement.class);

            for (IPackageExport pexport : bb.getExports())
            {
                info.addExport(pexport);
            }

            for (IPackageImport import1 : bb.getImports())
            {
                IPackageImport clone = (IPackageImport) import1.clone();
                clone.setParent(null);
                info.addImport(clone);
            }

            for (IRequiredBundle require : bb.getRequires())
            {
                IRequiredBundle clone = (IRequiredBundle) require.clone();
                clone.setParent(null);
                info.addRequiredBundle(clone);
            }

            info.setSymbolicName(bb.getSymbolicName());

            Version version = VersionTable.getVersion(bb.getVersion());
            info.setVersion(version);

            ISigilBundle pb = ModelElementFactory.getInstance().newModelElement(
                ISigilBundle.class);
            pb.setBundleInfo(info);

            Map<Object, Object> meta = new HashMap<Object, Object>();
            ModuleDescriptor md = SigilParser.instance().parseDescriptor(uri.toURL());
            if (!bb.getId().equals(md.getModuleRevisionId().getName()))
            { // non-default artifact
                for (Artifact a : md.getAllArtifacts())
                {
                    if (a.getName().equals(bb.getId()))
                    {
                        meta.put(Artifact.class, a);
                        break;
                    }
                }
            }

            meta.put(ModuleDescriptor.class, md);
            pb.setMeta(meta);

            list.add(pb);
            Log.debug("ProjectRepository: added " + pb);
            Log.debug("ProjectRepository: exports " + bb.getExports());
        }
    }
}
TOP

Related Classes of org.apache.felix.sigil.ivy.ProjectRepository

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.