Package org.apache.felix.sigil.eclipse.ui.internal.classpath

Source Code of org.apache.felix.sigil.eclipse.ui.internal.classpath.SigilClassPathContainer

/*
* 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.eclipse.ui.internal.classpath;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.job.ThreadProgressMonitor;
import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
import org.apache.felix.sigil.eclipse.ui.SigilUI;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;

/**
* @author dave
*
*/
public class SigilClassPathContainer implements IClasspathContainer
{

    private static final String CLASSPATH = "classpath";
    private static final String EMPTY = "empty";

    private IClasspathEntry[] entries;
   
    private final ISigilProjectModel sigil;
   
    public SigilClassPathContainer(ISigilProjectModel sigil)
    {
        this.sigil = sigil;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.core.IClasspathContainer#getClasspathEntries()
     */
    public IClasspathEntry[] getClasspathEntries()
    {
        if (entries == null)
        {
            buildClassPathEntries();
        }

        return entries;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.core.IClasspathContainer#getDescription()
     */
    public String getDescription()
    {
        return "Bundle Context Classpath";
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.core.IClasspathContainer#getKind()
     */
    public int getKind()
    {
        return K_SYSTEM;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.core.IClasspathContainer#getPath()
     */
    public IPath getPath()
    {
        return new Path(SigilCore.CLASSPATH_CONTAINER_PATH);
    }

    /**
     * @return
     * @throws CoreException
     * @throws CoreException
     */
    private void buildClassPathEntries()
    {
        try
        {
            if (sigil.exists()) {
                entries = getCachedClassPath(sigil);
               
                if ( entries == null ) {
                    IProgressMonitor monitor = ThreadProgressMonitor.getProgressMonitor();
                    entries = sigil.findExternalClasspath(monitor).toArray(new IClasspathEntry[0]);
                   
                    cacheClassPath(sigil, entries);
                }
            }
        }
        catch (CoreException e)
        {
            SigilCore.error("Failed to build classpath entries", e);
        }
        finally
        {
            if (entries == null)
            {
                entries = new IClasspathEntry[] {};
            }
        }
    }
   
    static IClasspathEntry[] getCachedClassPath(ISigilProjectModel project) {
        File f = getClassPathDir(project);
        if ( f == null || !f.exists() ) return null;
       
        File[] entries = f.listFiles();
        if ( entries == null || entries.length == 0 ) return null;
       
        ArrayList<IClasspathEntry> list = new ArrayList<IClasspathEntry>(entries.length);
        for(File entry : entries ) {
            if ( EMPTY.equals(entry.getName() ) ) {
                list.clear();
                break;
            }
            else {
                try
                {
                    list.add(readClassPath(project.getJavaModel(), entry));
                }
                catch (IOException e)
                {
                    SigilCore.warn("Failed to read classpath entry " + entry, e);
                }
            }
        }
        return list.toArray(new IClasspathEntry[list.size()]);
    }

    private static File getClassPathDir(ISigilProjectModel project)
    {
        IPath loc = project.getProject().getWorkingLocation(SigilUI.PLUGIN_ID);
       
        if ( loc == null ) return null;
       
        loc = loc.append(CLASSPATH);
       
        return new File(loc.toOSString());
    }

    static void cacheClassPath(ISigilProjectModel project, IClasspathEntry[] entries)
    {
        File f = getClassPathDir(project);
       
        if ( f == null ) return;
       
        if ( !f.exists() ) {
            if (!f.mkdirs()) {
                SigilCore.warn("Failed to create temp working directory " + f);
                return;
            }
        }
       
        try
        {
            if (entries.length == 0)
            {
                File empty = new File(f, EMPTY);
                empty.createNewFile();
            }
            else {
                int i = 0;
                for(IClasspathEntry e : entries) {
                    File entry = new File(f, Integer.toString(i++));
                    writeClassPath(project.getJavaModel(), entry, e);
                }
            }
        }
        catch (IOException e)
        {
            SigilCore.warn("Failed to read write classpath entries", e);
        }
    }

    /**
     * @param sigil
     */
    static void flushCachedClassPath(ISigilProjectModel project)
    {
        File f = getClassPathDir(project);
       
        if ( f == null || !f.exists() ) return;
       
        File[] files = f.listFiles();
        if ( files == null ) return;
       
        for (File entry : files) {
            entry.delete();
        }
    }
   
    private static IClasspathEntry readClassPath(IJavaProject javaModel, File entry) throws IOException
    {
        FileInputStream in = new FileInputStream(entry);
       
        try
        {
            ByteArrayOutputStream buf = new ByteArrayOutputStream();
           
            byte[] b = new byte[1024];
           
            for(;;) {
                int r = in.read(b);
                if ( r == -1 ) break;
                buf.write(b, 0, r);
            }
           
            String enc = buf.toString();
            return javaModel.decodeClasspathEntry(enc);
        }
        finally
        {
            try
            {
                in.close();
            }
            catch (IOException e)
            {
                SigilCore.warn("Failed to close stream to " + entry, e);
            }
        }
    }

    private static void writeClassPath(IJavaProject javaModel, File file, IClasspathEntry entry) throws IOException
    {
        String enc = javaModel.encodeClasspathEntry(entry);
        FileOutputStream out = new FileOutputStream(file);
        try {
            out.write(enc.getBytes());
            out.flush();
        }
        finally {
            try
            {
                out.close();
            }
            catch (IOException e)
            {
                SigilCore.warn("Failed to close stream to " + entry, e);
            }           
        }
    }
   
}
TOP

Related Classes of org.apache.felix.sigil.eclipse.ui.internal.classpath.SigilClassPathContainer

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.