moskitt4me.repositoryClient.core.util.RepositoryClientUtil.java Source code

Java tutorial

Introduction

Here is the source code for moskitt4me.repositoryClient.core.util.RepositoryClientUtil.java

Source

package moskitt4me.repositoryClient.core.util;

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import moskitt4me.repositoryClient.core.views.RepositoriesView;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.undo.CreateProjectOperation;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * A set of utility methods for the repository client of MOSKitt4ME
 *
 * @author Mario Cervera
 */
public class RepositoryClientUtil {

    /*
     * This method establishes a connection with a given FTP repository location.
     * The method uses a client that is provided by the Apache Commons project
     */
    public static FTPClient connect(RepositoryLocation location, boolean showErrors) {

        FTPClient client = new FTPClient();
        String errorMessage = "";

        try {
            client.connect(location.getHost());
            boolean ok = client.login(location.getUser(), location.getPassword());
            if (ok) {
                boolean ok2 = client.changeWorkingDirectory(location.getRepositoryPath());
                if (!ok2) {
                    client = null;
                    errorMessage = "Incorrect repository path";
                }
            } else {
                client = null;
                errorMessage = "Incorrect user name and password";
            }
        } catch (Exception e) {
            client = null;
            errorMessage = "Unknown host";
        }

        if (!errorMessage.equals("") && showErrors) {
            MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                    "Connection failed", errorMessage);
        }

        return client;
    }

    /*
     * This method disconnects the repository client from the repository
     */
    public static void disconnect(FTPClient client) {

        try {
            client.disconnect();
        } catch (Exception e) {

        }
    }

    /*
     * This method creates a folder in a given path.
     */
    public static String createFolder(String path, int index) {

        String newPath = path + index;

        String createdFolderPath = "";

        File folder = new File(newPath);
        if (!folder.exists()) {
            folder.mkdirs();
            createdFolderPath = newPath;
        } else {
            createdFolderPath = createFolder(path, index + 1);
        }

        return createdFolderPath;
    }

    /*
     * This method removes a folder (given the java.io.File object that points to it)
     */
    public static void removeFolder(File f) {

        if (f.isDirectory()) {
            File[] files = f.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    removeFolder(files[i]);
                } else {
                    files[i].delete();
                }
            }
        }
        f.delete();
    }

    /*
     * This method downloads a method fragment (that is, a .ras.zip file) from a repository.
     * The fragment is stored in a temporal folder
     * Input: the repository location and the name of the file that stores the fragment
     */
    public static String downloadFragment(RepositoryLocation location, String fileName) throws IOException {

        FTPClient client = RepositoryClientUtil.connect(location, false);
        String tempDir = "";

        if (client != null) {

            String eclipseInstallationDirectory = Platform.getInstallLocation().getURL().getPath();

            tempDir = RepositoryClientUtil.createFolder(eclipseInstallationDirectory + "tmp", 0);

            //Download the file

            String destination = tempDir + "/" + fileName;
            FileOutputStream fos = new FileOutputStream(destination);
            client.retrieveFile(fileName, fos);
            fos.close();

            //Disconnect the client

            RepositoryClientUtil.disconnect(client);
        }

        return tempDir;
    }

    /*
     * This method downloads a method fragment (that is, a .ras.zip file) from a repository.
     * Input: the repository location, the name of the file that stores the fragment, and
     * the target directory
     */
    public static void downloadFragment(RepositoryLocation location, String fileName, String folder)
            throws IOException {

        FTPClient client = RepositoryClientUtil.connect(location, false);

        if (client != null) {

            //Download the file

            String destination = folder + "/" + fileName;
            FileOutputStream fos = new FileOutputStream(destination);
            client.retrieveFile(fileName, fos);
            fos.close();

            //Disconnect the client

            RepositoryClientUtil.disconnect(client);
        }
    }

    /*
     * This method returns whether a given fragment type corresponds to a technical fragment
     */
    public static boolean isTechnicalFragment(String type) {

        return (type.equals("Graphical Editor") || type.equals("Meta-Model") || type.equals("Form-based Editor")
                || type.equals("Model transformation") || type.equals("Guidance") || type.equals("External Tool")
                || type.equals("Internal Tool") || type.equals("Others"));
    }

    /*
     * This method extracts the content of a given zip file. This funcionality is used
     * to extract the content of method fragments
     */
    public static void extractZipFile(String folder, String zipName) throws Exception {

        ZipFile zipFile = new ZipFile(new File(folder + "/" + zipName));

        Enumeration entries = zipFile.entries();

        while (entries.hasMoreElements()) {
            Object obj = entries.nextElement();
            if (obj instanceof ZipEntry) {
                ZipEntry entry = (ZipEntry) obj;

                InputStream eis = zipFile.getInputStream(entry);
                byte[] buffer = new byte[1024];
                int bytesRead = 0;

                File f = new File(folder + "/" + entry.getName());

                if (entry.isDirectory()) {
                    f.mkdirs();
                    eis.close();
                    continue;
                } else {
                    f.getParentFile().mkdirs();
                    f.createNewFile();
                }

                FileOutputStream fos = new FileOutputStream(f);

                while ((bytesRead = eis.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                }

                if (eis != null) {
                    eis.close();
                }

                if (fos != null) {
                    fos.close();
                }
            }
        }

        zipFile.close();
    }

    /*
     * This method adds a new entry (file) to a zip file. This functionality is used to add content to
     * method fragments
     */
    public static void addFileToZip(File file, ZipOutputStream zos) throws Exception {

        zos.putNextEntry(new ZipEntry(file.getName()));

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

        long bytesRead = 0;
        byte[] bytesIn = new byte[1024];
        int read = 0;

        while ((read = bis.read(bytesIn)) != -1) {
            zos.write(bytesIn, 0, read);
            bytesRead += read;
        }

        zos.closeEntry();
        bis.close();
    }

    /*
     * This method adds a new entry (folder) to a zip file. This functionality is used to add content to
     * method fragments
     */
    public static void addFolderToZip(File folder, String parentFolder, ZipOutputStream zos) throws Exception {

        for (File file : folder.listFiles()) {

            if (file.isDirectory()) {
                zos.putNextEntry(new ZipEntry(parentFolder + file.getName() + "/"));
                zos.closeEntry();
                addFolderToZip(file, parentFolder + file.getName() + "/", zos);
                continue;
            } else {
                zos.putNextEntry(new ZipEntry(parentFolder + file.getName()));
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

                long bytesRead = 0;
                byte[] bytesIn = new byte[1024];
                int read = 0;

                while ((read = bis.read(bytesIn)) != -1) {
                    zos.write(bytesIn, 0, read);
                    bytesRead += read;
                }

                zos.closeEntry();
                bis.close();
            }
        }
    }

    /*
     * This method duplicates a folder by copying it into a new location
     */
    public static void copyDirectory(File sourceLocation, File targetLocation) throws Exception {

        if (sourceLocation.isDirectory()) {
            if (!targetLocation.exists()) {
                targetLocation.mkdirs();
                String[] children = sourceLocation.list();
                for (int i = 0; i < children.length; i++) {
                    File source = new File(sourceLocation, children[i]);
                    File target = new File(targetLocation, children[i]);
                    copyDirectory(source, target);
                }
            }
        } else {
            InputStream in = new FileInputStream(sourceLocation);
            OutputStream out = new FileOutputStream(targetLocation);

            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }
    }

    /*
     * This method returns the Repositories View of MOSKitt4ME
     */
    public static RepositoriesView getRepositoriesView() {

        try {
            IViewPart viewPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
                    .findView(RepositoriesView.RepositoriesViewId);

            if (viewPart instanceof RepositoriesView) {
                return (RepositoriesView) viewPart;
            }
        } catch (Exception e) {
            return null;
        }

        return null;
    }

    /*
     * This method creates a Feature Project grouping the plug-ins that are contained in a
     * given technical fragment
     */
    public static IProject createFeatureProject(TechnicalFragment tf) throws Exception {

        String featureName = tf.getName() + ".feature";

        IProjectDescription description = ResourcesPlugin.getWorkspace().newProjectDescription(featureName);

        description.setName(featureName);

        //Natures

        String[] natures = description.getNatureIds();
        String[] newNatures = new String[natures.length + 1];
        System.arraycopy(natures, 0, newNatures, 0, natures.length);

        newNatures[natures.length] = "org.eclipse.pde.FeatureNature";

        description.setNatureIds(newNatures);

        //Builders

        ICommand builderCommand = description.newCommand();
        builderCommand.setBuilderName("org.eclipse.pde.FeatureBuilder");

        ICommand[] oldCommands = description.getBuildSpec();
        ICommand[] newCommands = new ICommand[oldCommands.length + 1];

        System.arraycopy(oldCommands, 0, newCommands, 0, oldCommands.length);
        newCommands[oldCommands.length] = builderCommand;

        description.setBuildSpec(newCommands);

        //Project creation

        CreateProjectOperation op = new CreateProjectOperation(description, "New Feature Project");

        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();

        PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().execute(op, new NullProgressMonitor(),
                WorkspaceUndoUtil.getUIInfoAdapter(shell));

        Object[] objects = op.getAffectedObjects();
        if (objects.length == 1 && objects[0] instanceof IProject) {
            IProject feature = (IProject) objects[0];

            addBuildProperties(feature);
            addFeatureXML(feature, tf);

            feature.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());

            return feature;
        }

        return null;
    }

    private static void addBuildProperties(IProject feature) throws Exception {

        String featureLocation = feature.getLocation().toString();
        File f = new File(featureLocation + "/build.properties");
        if (!f.exists()) {
            f.createNewFile();
            BufferedWriter output = new BufferedWriter(new FileWriter(f));
            output.write("bin.includes = feature.xml\n");
            output.close();
        }
    }

    private static void addFeatureXML(IProject feature, TechnicalFragment tf) throws Exception {

        String featureLocation = feature.getLocation().toString();
        List<IProject> plugins = tf.getPlugins();
        File f = new File(featureLocation + "/feature.xml");
        if (!f.exists()) {
            f.createNewFile();
            BufferedWriter output = new BufferedWriter(new FileWriter(f));
            output.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            output.write(
                    "<feature id=\"" + feature.getName() + "\" label=\"Feature\" version=\"1.0.0.qualifier\">\n");
            output.write(
                    "<description url=\"http://www.example.com/description\"> [Enter Feature Description here.] </description>\n");
            output.write(
                    "<copyright url=\"http://www.example.com/copyright\"> [Enter Copyright Description here.] </copyright>\n");
            output.write(
                    "<license url=\"http://www.example.com/license\"> [Enter License Description here.] </license>\n");
            for (IProject project : plugins) {
                output.write("<plugin id=\"" + project.getName()
                        + "\" download-size=\"0\" install-size=\"0\" version=\"0.0.0\" unpack=\"false\"/>\n");
            }
            output.write("</feature>\n");
            output.close();
        }
    }

    /*
     * This method creates the rasset.xml file of a given technical fragment. This file represent the manifest
     * file of the fragment: it stores the fragment properties and its dependencies with other technical fragments
     */
    public static String createRassetXMLFile(TechnicalFragment tf, String folder) throws Exception {

        String manifestPath = folder + "/rasset.xml";
        File f = new File(manifestPath);
        if (!f.exists()) {
            f.createNewFile();

            String type = tf.getType();
            String origin = type.equals("Others") ? "no origin" : tf.getOrigin();
            String objective = type.equals("Others") ? "no objective" : tf.getObjective();
            String input = type.equals("Others") ? "no input" : tf.getInput();
            String output = type.equals("Others") ? "no output" : tf.getOutput();
            String toolId = getToolId(tf);
            String description = "";
            if (type.equals("External Tool")) {
                description = ((ExternalToolFragment) tf).getDescription();
            } else if (type.equals("Internal Tool")) {
                description = ((InternalToolFragment) tf).getDescription();
            } else {
                description = "no description";
            }

            BufferedWriter bwriter = new BufferedWriter(new FileWriter(f));
            bwriter.write("<asset xsi:schemaLocation=\"DefaultprofileXML.xsd\" name=\"" + tf.getName()
                    + "\" id=\"1\">\n");
            bwriter.write("<type value=\"" + type + "\"></type>\n");
            bwriter.write("<origin value=\"" + origin + "\"></origin>\n");
            bwriter.write("<objective value=\"" + objective + "\"></objective>\n");
            bwriter.write("<input value=\"" + input + "\"></input>\n");
            bwriter.write("<output value=\"" + output + "\"></output>\n");
            if (toolId != null && !toolId.equals("")) {
                bwriter.write("<toolID value=\"" + toolId + "\"></toolID>\n");
            }
            bwriter.write("<description>" + description + "</description>\n");
            List<TechnicalFragment> dependencies = tf.getDependencies();
            for (TechnicalFragment dependency : dependencies) {
                bwriter.write("<dependency value=\"" + dependency.getName() + ".ras.zip\"></dependency>\n");
            }
            if (type.equals("Internal Tool")) {
                List<String> pluginIds = ((InternalToolFragment) tf).getPluginIds();
                for (String pluginId : pluginIds) {
                    bwriter.write("<plugin value=\"" + pluginId + "\"></plugin>\n");
                }
            }
            bwriter.write("</asset>\n");
            bwriter.close();
        }

        return manifestPath;
    }

    /*
     * This method returns the id of the tool stored in a technical fragment.
     */
    private static String getToolId(TechnicalFragment tf) {

        String type = tf.getType();

        if (type.equals("Others") || type.equals("Internal Tool")) {
            return "";
        }
        if (type.equals("External Tool")) {
            ExternalToolFragment etf = (ExternalToolFragment) tf;
            String fileExtension = etf.getFileExtension();
            if (!fileExtension.startsWith(".")) {
                fileExtension = "." + fileExtension;
            }
            return fileExtension;
        }

        List<IProject> plugins = tf.getPlugins();

        for (IProject plugin : plugins) {
            String pluginLocation = plugin.getLocation().toString();
            String pluginXMLLocation = pluginLocation + "/plugin.xml";

            Document pluginXMLDocument = getDocument(pluginXMLLocation);
            if (pluginXMLDocument != null) {

                String extensionPointId = "";
                String elementId = "";
                String attribute = "";

                if (type.equals("Graphical Editor") || type.equals("Meta-Model")
                        || type.equals("Form-based Editor")) {
                    extensionPointId = "org.eclipse.ui.newWizards";
                    elementId = "wizard";
                    attribute = "id";
                } else if (type.equals("Model transformation")) {
                    extensionPointId = "es.cv.gvcase.trmanager.transformation";
                    elementId = "transformation";
                    attribute = "id";
                } else if (type.equals("Guidance")) {
                    extensionPointId = "org.eclipse.epf.authoring.ui.helpcontextprovider";
                    elementId = "helpContextProviderDesc";
                    attribute = "idContext";
                }

                if (!extensionPointId.equals("")) {
                    NodeList extension = pluginXMLDocument.getElementsByTagName("extension");
                    int length = extension.getLength();
                    for (int i = 0; i < length; i++) {
                        Node extensionNode = extension.item(i);
                        if (extensionNode.getAttributes().getNamedItem("point").getNodeValue()
                                .equals(extensionPointId) && extensionNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element extensionElement = (Element) extensionNode;
                            NodeList elements = extensionElement.getElementsByTagName(elementId);
                            if (elements.getLength() > 0) {
                                Node element = elements.item(0);
                                String attValue = element.getAttributes().getNamedItem(attribute).getNodeValue();
                                if (type.equals("Guidance")) {
                                    return plugin.getName() + "." + attValue;
                                } else {
                                    return attValue;
                                }
                            }
                        }
                    }
                }
            }
        }

        return "";
    }

    public static Document getDocument(String path) {

        Document document = null;

        try {
            File f = new File(path);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            document = db.parse(f);

        } catch (Exception e) {

        }

        return document;
    }

    /*
     * This method returns a Plug-in Project given its name
     */
    public static IProject getPluginProject(String projectName) {

        List<IProject> plugins = getPluginProjects();

        for (IProject plugin : plugins) {
            if (plugin.getName().equals(projectName)) {
                return plugin;
            }
        }
        return null;
    }

    /*
     * This method returns the Plug-in Projects of the MOSKitt4ME workspace
     */
    private static List<IProject> getPluginProjects() {

        List<IProject> pluginProjects = new ArrayList<IProject>();
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

        IProject[] projects = root.getProjects();

        for (IProject project : projects) {
            try {
                if (project.hasNature("org.eclipse.pde.PluginNature")) {
                    pluginProjects.add(project);
                }
            } catch (CoreException e) {

            }
        }
        return pluginProjects;
    }

    /*
     * This method takes a set of projects from a source path and imports them in the MOSKitt4ME workspace
     */
    public static IProject importProjectIntoWorkspace(String path) throws Exception {

        IProjectDescription description = null;

        try {

            description = ResourcesPlugin.getWorkspace().loadProjectDescription(new Path(path + "/.project"));

        } catch (Exception e) {

        }

        if (description != null) {
            IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(description.getName());
            project.create(description, null);
            project.open(null);

            return project;
        }

        return null;
    }

    /*
     * This method reads a rasset.xml file and loads the information into a technical fragment object (tf).
     * It returns the dependencies of the technical fragment.
     */
    public static List<TechnicalFragment> parseRassetXML(String path, TechnicalFragment tf) {

        List<TechnicalFragment> dependencies = new ArrayList<TechnicalFragment>();

        Document doc = getDocument(path);
        if (doc != null) {
            if (doc != null) {
                Node type = doc.getElementsByTagName("type").item(0);
                Node origin = doc.getElementsByTagName("origin").item(0);
                Node objective = doc.getElementsByTagName("objective").item(0);
                Node input = doc.getElementsByTagName("input").item(0);
                Node output = doc.getElementsByTagName("output").item(0);

                tf.setType(type.getAttributes().getNamedItem("value").getNodeValue());
                tf.setOrigin(origin.getAttributes().getNamedItem("value").getNodeValue());
                tf.setObjective(objective.getAttributes().getNamedItem("value").getNodeValue());
                tf.setInput(input.getAttributes().getNamedItem("value").getNodeValue());
                tf.setOutput(output.getAttributes().getNamedItem("value").getNodeValue());

                NodeList deps = doc.getElementsByTagName("dependency");
                int length = deps.getLength();
                for (int i = 0; i < length; i++) {
                    Node depNode = deps.item(i);
                    String depName = depNode.getAttributes().getNamedItem("value").getNodeValue();
                    String extension = ".ras.zip";
                    String assetName = depName.substring(0, depName.length() - extension.length());
                    TechnicalFragment asset = new TechnicalFragment(assetName, "", "", "", "", "");
                    dependencies.add(asset);
                }
            }
        }

        return dependencies;
    }

    public static void setInitialLocationType(RepositoryLocation location) {

        FTPClient client = RepositoryClientUtil.connect(location, false);

        if (client != null) {

            String tempDir = "";

            try {
                String eclipseInstallationDirectory = Platform.getInstallLocation().getURL().getPath();
                tempDir = RepositoryClientUtil.createFolder(eclipseInstallationDirectory + "tmp", 0);

                FTPFile[] files = client.listFiles();

                if (files.length > 0) {
                    String fileName = files[0].getName();
                    String destination = tempDir + "/" + fileName;
                    FileOutputStream fos = new FileOutputStream(destination);
                    client.retrieveFile(fileName, fos);
                    fos.close();

                    extractZipFile(tempDir, fileName);

                    Document doc = getDocument(tempDir + "/rasset.xml");
                    if (doc != null) {
                        Node ntype = doc.getElementsByTagName("type").item(0);
                        String type = ntype.getAttributes().getNamedItem("value").getNodeValue();
                        if (type != null) {
                            if (isTechnicalFragment(type)) {
                                location.setType("Technical");
                            } else {
                                location.setType("Conceptual");
                            }
                        }
                    }
                } else {
                    location.setType("Empty");
                }
            } catch (Exception e) {

            } finally {
                RepositoryClientUtil.disconnect(client);
                if (location.getType().equals("")) {
                    location.setType("Empty");
                }
                if (!tempDir.equals("")) {
                    RepositoryClientUtil.removeFolder(new File(tempDir));
                }
            }
        }
    }

}