Package org.apache.felix.sigil.common.core.internal.model.eclipse

Source Code of org.apache.felix.sigil.common.core.internal.model.eclipse.SigilBundle

/*
* 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.common.core.internal.model.eclipse;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.jar.JarFile;

import org.apache.felix.sigil.common.config.Resource;
import org.apache.felix.sigil.common.core.BldCore;
import org.apache.felix.sigil.common.model.AbstractCompoundModelElement;
import org.apache.felix.sigil.common.model.eclipse.IBundleCapability;
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.progress.IProgress;
import org.apache.felix.sigil.common.util.ManifestUtil;
import org.osgi.framework.Version;

/**
* @author dave
*
*/
public class SigilBundle extends AbstractCompoundModelElement implements ISigilBundle
{

    private static final long serialVersionUID = 1L;

    private IBundleModelElement bundle;
    private Resource[] sourcePaths;
    private String[] classpath;
    private String[] packages;
    private File location;

    private File sourcePathLocation;
    private File licencePathLocation;
    private String sourceRootPath;

    public SigilBundle()
    {
        super("Sigil Bundle");
        sourcePaths = new Resource[0];
        classpath = new String[0];
        packages = new String[0];
    }
   
    public void synchronize(IProgress progress) throws IOException
    {
        progress = progress.newTask(100);
        progress.report("Synchronizing " + bundle.getSymbolicName() + " binary");
        sync(location, bundle.getUpdateLocation(), progress.newChild(45));

        if (bundle.getSourceLocation() != null)
        {
            try
            {
                progress.report("Synchronizing " + bundle.getSymbolicName() + " source");
                sync(sourcePathLocation, bundle.getSourceLocation(),
                    progress.newChild(45));
            }
            catch (IOException e)
            {
                BldCore.error("Failed to download source for " + bundle.getSymbolicName()
                    + " " + bundle.getVersion(), e.getCause());
            }
        }

        if (bundle.getLicenseURI() != null)
        {
            try
            {
                progress.report("Synchronizing " + bundle.getSymbolicName() + " licence");
                sync(licencePathLocation, bundle.getLicenseURI(), progress.newChild(10));
            }
            catch (IOException e)
            {
                BldCore.error("Failed to download licence for "
                    + bundle.getSymbolicName() + " " + bundle.getVersion(), e.getCause());
            }
        }

        updateManifest(location);
    }

    private void updateManifest(File location) throws IOException
    {
        if (location != null && location.exists())
        {
            JarFile f = new JarFile(location, false);
            try
            {
                setBundleInfo(ManifestUtil.buildBundleModelElement(f));
            }
            finally
            {
                f.close();
            }
        }
    }

    public boolean isSynchronized()
    {
        return location == null || location.exists();
    }

    private static void sync(File local, URI remote, IProgress progress)
        throws IOException
    {
        try
        {
            if (remote != null)
            {
                if (local != null && !local.exists())
                {
                    URL url = remote.toURL();
                    URLConnection connection = url.openConnection();
                    int contentLength = connection.getContentLength();

                    progress = progress.newTask(contentLength);
                    progress.report("Downloading from " + url.getHost());

                    InputStream in = null;
                    OutputStream out = null;
                    try
                    {
                        URLConnection conn = url.openConnection();
                        if (conn instanceof HttpURLConnection)
                        {
                            HttpURLConnection http = (HttpURLConnection) conn;
                            http.setConnectTimeout(10000);
                            http.setReadTimeout(5000);
                        }
                        in = conn.getInputStream();
                        local.getParentFile().mkdirs();
                        out = new FileOutputStream(local);
                        stream(in, out, progress);
                    }
                    finally
                    {
                        if (in != null)
                        {
                            in.close();
                        }
                        if (out != null)
                        {
                            out.close();
                        }
                        progress.done();
                    }
                }
            }
        }
        catch (IOException e)
        {
            local.delete();
            throw e;
        }
    }

    private static void stream(InputStream in, OutputStream out, IProgress progress)
        throws IOException
    {
        byte[] b = new byte[1024];
        for (;;)
        {
            if (progress.isCanceled())
            {
                throw new InterruptedIOException("User canceled download");
            }
            int r = in.read(b);
            if (r == -1)
                break;
            out.write(b, 0, r);
            progress.worked(r);
        }

        out.flush();
    }

    public IBundleModelElement getBundleInfo()
    {
        return bundle;
    }

    public void setBundleInfo(IBundleModelElement bundle)
    {
        if (bundle == null)
        {
            if (this.bundle != null)
            {
                this.bundle.setParent(null);
            }
        }
        else
        {
            bundle.setParent(this);
        }
        this.bundle = bundle;
    }

    public void addSourcePath(Resource path)
    {
        ArrayList<Resource> tmp = new ArrayList<Resource>(getSourcePaths());
        tmp.add(path);
        sourcePaths = tmp.toArray(new Resource[tmp.size()]);
    }

    public void removeSourcePath(Resource path)
    {
        ArrayList<Resource> tmp = new ArrayList<Resource>(getSourcePaths());
        if (tmp.remove(path))
        {
            sourcePaths = tmp.toArray(new Resource[tmp.size()]);
        }
    }

    public Collection<Resource> getSourcePaths()
    {
        return Arrays.asList(sourcePaths);
    }

    public void clearSourcePaths()
    {
        sourcePaths = new Resource[0];
    }

    public void addClasspathEntry(String encodedClasspath)
    {
        encodedClasspath = encodedClasspath.trim();
        ArrayList<String> tmp = new ArrayList<String>(getClasspathEntrys());
        if (!tmp.contains(encodedClasspath)) {
            tmp.add(encodedClasspath);
            classpath = tmp.toArray(new String[tmp.size()]);
        }
    }

    public Collection<String> getClasspathEntrys()
    {
        return Arrays.asList(classpath);
    }

    public void removeClasspathEntry(String encodedClasspath)
    {
        ArrayList<String> tmp = new ArrayList<String>(getClasspathEntrys());
        if (tmp.remove(encodedClasspath.trim()))
        {
            classpath = tmp.toArray(new String[tmp.size()]);
        }
    }

    public File getLocation()
    {
        return location;
    }

    public void setLocation(File location)
    {
        this.location = location;
    }

    public File getSourcePathLocation()
    {
        return sourcePathLocation;
    }

    public void setSourcePathLocation(File location)
    {
        this.sourcePathLocation = location;
    }

    public String getSourceRootPath()
    {
        return sourceRootPath;
    }

    public void setSourceRootPath(String location)
    {
        this.sourceRootPath = location;
    }

    public File getLicencePathLocation()
    {
        return licencePathLocation;
    }

    public void setLicencePathLocation(File licencePathLocation)
    {
        this.licencePathLocation = licencePathLocation;
    }

    public String getElementName()
    {
        return bundle.getSymbolicName();
    }

    public Version getVersion()
    {
        return bundle.getVersion();
    }

    public void setVersion(Version version)
    {
        this.bundle.setVersion(version);
    }

    public String getSymbolicName()
    {
        return bundle.getSymbolicName();
    }

    public Collection<String> getPackages()
    {
        return Arrays.asList(packages);
    }

    public void addPackage(String pkg)
    {
        ArrayList<String> tmp = new ArrayList<String>(getPackages());
        tmp.add(pkg);
        packages = tmp.toArray(new String[tmp.size()]);
    }

    public boolean removePackage(String pkg)
    {
        ArrayList<String> tmp = new ArrayList<String>(getPackages());
        if (tmp.remove(pkg))
        {
            packages = tmp.toArray(new String[tmp.size()]);
            return true;
        }
        else
        {
            return false;
        }
    }

    public IPackageExport findExport(String packageName)
    {
        for (IPackageExport e : bundle.getExports())
        {
            if (packageName.equals(e.getPackageName()))
            {
                return e;
            }
        }
        return null;
    }

    public IPackageImport findImport(String packageName)
    {
        for (IPackageImport i : bundle.getImports())
        {
            if (packageName.equals(i.getPackageName()))
            {
                return i;
            }
        }
        return null;
    }

    @Override
    public String toString()
    {
        return "SigilBundle["
            + (getBundleInfo() == null ? null
                : (getBundleInfo().getSymbolicName() + ":" + getBundleInfo().getVersion()))
            + "]";
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj == null)
            return false;
        if (obj == this)
            return true;

        if (obj instanceof SigilBundle)
        {
            return obj.toString().equals(toString());
        }

        return false;
    }

    @Override
    public int hashCode()
    {
        return 31 * toString().hashCode();
    }

    @Override
    public SigilBundle clone()
    {
        SigilBundle b = (SigilBundle) super.clone();
        b.bundle = (IBundleModelElement) b.bundle.clone();

        Resource[] newPaths = new Resource[b.sourcePaths.length];
        System.arraycopy(b.sourcePaths, 0, newPaths, 0, b.sourcePaths.length);
        b.sourcePaths = newPaths;

        String[] tmp = new String[classpath.length];
        System.arraycopy(b.classpath, 0, tmp, 0, b.classpath.length);
        b.classpath = tmp;

        tmp = new String[packages.length];
        System.arraycopy(b.packages, 0, tmp, 0, b.packages.length);
        b.packages = tmp;

        return b;
    }

    public IBundleCapability getBundleCapability()
    {
        return new BundleCapability(bundle);
    }
}
TOP

Related Classes of org.apache.felix.sigil.common.core.internal.model.eclipse.SigilBundle

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.