org.whole.lang.artifacts.util.ArtifactsWorkspaceUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.whole.lang.artifacts.util.ArtifactsWorkspaceUtils.java

Source

/**
 * Copyright 2004-2014 Riccardo Solmi. All rights reserved.
 * This file is part of the Whole Platform.
 *
 * The Whole Platform is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The Whole Platform is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
 */
package org.whole.lang.artifacts.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
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.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.whole.lang.artifacts.factories.ArtifactsEntityFactory;
import org.whole.lang.artifacts.model.Artifact;
import org.whole.lang.artifacts.model.AttributeEnum;
import org.whole.lang.artifacts.model.Content;
import org.whole.lang.artifacts.model.FileArtifact;
import org.whole.lang.artifacts.model.FileName;
import org.whole.lang.artifacts.model.FolderArtifact;
import org.whole.lang.artifacts.model.Metadata;
import org.whole.lang.artifacts.model.NameWithExtension;
import org.whole.lang.artifacts.model.PackageArtifact;
import org.whole.lang.artifacts.model.PersistenceKitId;
import org.whole.lang.artifacts.model.Project;
import org.whole.lang.artifacts.model.Workspace;
import org.whole.lang.artifacts.reflect.ArtifactsEntityDescriptorEnum;
import org.whole.lang.artifacts.reflect.ArtifactsFeatureDescriptorEnum;
import org.whole.lang.artifacts.visitors.LoadContentsVisitor;
import org.whole.lang.bindings.BindingManagerFactory;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.codebase.IFilePersistenceProvider;
import org.whole.lang.codebase.IPersistenceKit;
import org.whole.lang.codebase.IPersistenceProvider;
import org.whole.lang.commons.factories.CommonsEntityAdapterFactory;
import org.whole.lang.commons.factories.CommonsEntityFactory;
import org.whole.lang.commons.model.Resolver;
import org.whole.lang.commons.reflect.CommonsEntityDescriptorEnum;
import org.whole.lang.factories.RegistryConfigurations;
import org.whole.lang.iterators.CollectionIterator;
import org.whole.lang.iterators.IEntityIterator;
import org.whole.lang.iterators.IteratorFactory;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.model.NullEntity;
import org.whole.lang.reflect.ILanguageKit;
import org.whole.lang.reflect.ReflectionFactory;
import org.whole.lang.util.EntityUtils;
import org.whole.lang.util.StringUtils;

/**
 * @author Riccardo Solmi, Enrico Persiani
 */
public class ArtifactsWorkspaceUtils {

    public static boolean existsPath(IEntity artifact) {
        return existsPath(artifact, null);
    }

    public static boolean existsPath(IEntity artifact, IEntity childArtifact) {
        try {
            IBindingManager bindings = BindingManagerFactory.instance.createBindingManager();
            bindPath(artifact, bindings, false);
            if (childArtifact != null) {
                IFolder parentFolder = (IFolder) bindings.wGetValue("folder");
                return parentFolder
                        .exists(parentFolder.getFullPath().append(ArtifactsUtils.getName(childArtifact)));
            } else
                return true;
        } catch (IllegalArgumentException e) {
            return false;
        }
    }

    public static void bindPath(IEntity artifact, IBindingManager bindings, boolean force) {
        if (!ArtifactsEntityDescriptorEnum.Artifact.isLanguageSupertypeOf(artifact.wGetEntityDescriptor())
                && !Matcher.match(ArtifactsEntityDescriptorEnum.Workspace, artifact)
                && !Matcher.match(ArtifactsEntityDescriptorEnum.Project, artifact))
            throw new IllegalArgumentException("Wrong path ending with: " + artifact.toString());

        IEntityIterator<IEntity> pathIterator = new AncestorOrSelfInSameLanguageReverseIterator();
        pathIterator.reset(artifact);

        if (!pathIterator.hasNext())
            throw new IllegalArgumentException("Empty model");

        if (CommonsEntityDescriptorEnum.RootFragment.equals(pathIterator.lookahead().wGetEntityDescriptor()))
            pathIterator.next();

        IEntity rootEntity = pathIterator.next();
        if (!Matcher.matchImpl(ArtifactsEntityDescriptorEnum.Workspace, rootEntity))
            throw new IllegalArgumentException("Missing Workspace root entity");

        bindMetadata(((Workspace) rootEntity).getMetadata(), bindings);

        while (pathIterator.hasNext()) {
            IEntity pathFragment = pathIterator.next();
            if (EntityUtils.isNotResolver(pathFragment) && !EntityUtils.isComposite(pathFragment)) {
                switch (pathFragment.wGetEntityOrd()) {
                case ArtifactsEntityDescriptorEnum.Project_ord:
                    bindProject((Project) pathFragment, bindings, force);
                    break;
                case ArtifactsEntityDescriptorEnum.FolderArtifact_ord:
                    bindFolder((FolderArtifact) pathFragment, bindings, force);
                    break;
                case ArtifactsEntityDescriptorEnum.PackageArtifact_ord:
                    bindPackage((PackageArtifact) pathFragment, bindings, force);
                    break;
                case ArtifactsEntityDescriptorEnum.FileArtifact_ord:
                    bindFile((FileArtifact) pathFragment, bindings, force);
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported entity in path: " + pathFragment.toString());
                }
            }
        }
    }

    private static void bindProject(Project projectEntity, IBindingManager bindings, boolean force) {
        bindings.wEnterScope();
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        if (!Matcher.matchImplAndBind(ArtifactsEntityDescriptorEnum.Name, projectEntity.getName(), bindings,
                "projectName"))
            throw new IllegalArgumentException("No Project name");
        bindMetadata(projectEntity.getMetadata(), bindings);
        IProject project = workspaceRoot.getProject(bindings.wStringValue("projectName"));
        bindings.wDefValue("project", project);

        if (!project.exists()) {
            if (!force)
                throw new IllegalArgumentException("Missing Project: " + bindings.wStringValue("projectName"));
            else {
                try {
                    project.create((IProgressMonitor) bindings.wGetValue("progressMonitor"));
                    if (project.hasNature(JavaCore.NATURE_ID))
                        bindings.wDefValue("javaProject", JavaCore.create(project));
                } catch (CoreException e) {
                    throw new IllegalArgumentException(
                            "Cannot create Project: " + bindings.wStringValue("projectName"));
                }
            }
        }
        bindings.wExitScope(true);
    }

    private static void bindFolder(FolderArtifact folderEntity, IBindingManager bindings, boolean force) {
        bindings.wEnterScope();
        if (!Matcher.matchImplAndBind(ArtifactsEntityDescriptorEnum.Name, folderEntity.getName(), bindings,
                "folderName"))
            throw new IllegalArgumentException("No Folder name");
        bindMetadata(folderEntity.getMetadata(), bindings);
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        IFolder folder = workspaceRoot
                .getFolder(getParentPath(bindings).append(bindings.wStringValue("folderName")));
        bindings.wDefValue("folder", folder);
        if (!folder.exists()) {
            if (!force)
                throw new IllegalArgumentException("Missing Folder: " + bindings.wStringValue("folderName"));
            else {
                try {
                    folder.create(true, true, (IProgressMonitor) bindings.wGetValue("progressMonitor"));
                } catch (Exception e) {
                    throw new IllegalArgumentException(
                            "Cannot create Folder: " + bindings.wStringValue("folderName"));
                }
            }
        }
        bindings.wExitScope(true);
    }

    private static void bindPackage(PackageArtifact packageEntity, IBindingManager bindings, boolean force) {
        bindings.wEnterScope();
        if (!Matcher.matchImplAndBind(ArtifactsEntityDescriptorEnum.Name, packageEntity.getName(), bindings,
                "packageName"))
            throw new IllegalArgumentException("No Folder name");
        bindMetadata(packageEntity.getMetadata(), bindings);
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        IFolder folder = workspaceRoot.getFolder(
                getParentPath(bindings).append(StringUtils.packagePath(bindings.wStringValue("packageName"))));
        bindings.wDefValue("folder", folder);
        if (!folder.exists()) {
            if (!force)
                throw new IllegalArgumentException("Missing Package: " + bindings.wStringValue("packageName"));
            else {
                try {
                    folder.create(true, true, (IProgressMonitor) bindings.wGetValue("progressMonitor"));
                } catch (Exception e) {
                    throw new IllegalArgumentException(
                            "Cannot create Package: " + bindings.wStringValue("packageName"));
                }
            }
        }
        bindings.wExitScope(true);
    }

    private static void bindFile(FileArtifact fileEntity, IBindingManager bindings, boolean force) {
        bindings.wEnterScope();
        if (!Matcher.matchImplAndBind(ArtifactsEntityDescriptorEnum.Name, fileEntity.getName(), bindings,
                "fileName")) {
            NameWithExtension name = (NameWithExtension) fileEntity.getName();
            if (!Matcher.matchImplAndBind(ArtifactsEntityDescriptorEnum.Name, name.getName(), bindings, "fileName"))
                throw new IllegalArgumentException("No File name");
            if (!Matcher.matchImplAndBind(ArtifactsEntityDescriptorEnum.Extension, name.getExtension(), bindings,
                    "extension"))
                throw new IllegalArgumentException("No File name");
        }
        bindMetadata(fileEntity.getMetadata(), bindings);
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        IFile file = workspaceRoot.getFile(getParentPath(bindings).append(bindings.wIsSet("extension")
                ? bindings.wStringValue("fileName") + '.' + bindings.wStringValue("extension")
                : bindings.wStringValue("fileName")));
        bindings.wDefValue("file", file);
        if (!file.exists() && !force)
            throw new IllegalArgumentException("Missing File: " + bindings.wStringValue("fileName"));
        bindings.wExitScope(true);
    }

    private static void bindMetadata(Metadata metadata, IBindingManager bindings) {
        if (!EntityUtils.isImpl(metadata))
            return;

        PersistenceKitId persistenceKitId = metadata.getPersistenceKitId();
        if (EntityUtils.isImpl(persistenceKitId))
            bindings.wDef("persistenceKitId", persistenceKitId);
    }

    public static IPath getParentPath(IBindingManager bindings) {
        IPath parentPath;
        if (bindings.wIsSet("folder")) {
            IFolder parentFolder = (IFolder) bindings.wGetValue("folder");
            parentPath = parentFolder.getFullPath();
        } else {
            IProject project = (IProject) bindings.wGetValue("project");
            parentPath = project.getFullPath();
        }
        return parentPath;
    }

    public static IEntity toArtifactsPath(IResource fromResource, IResource toResource) {
        return toArtifactsPath(fromResource, toResource, NullEntity.instance);
    }

    public static IEntity toArtifactsPath(IResource fromResource, IResource toResource, IEntity child) {
        ArtifactsEntityFactory aef = ArtifactsEntityFactory.instance(RegistryConfigurations.RESOLVER);

        IEntity entity;
        String name = toResource.getName();
        switch (toResource.getType()) {
        case IResource.FILE:
            FileArtifact fileArtifact = aef.createFileArtifact();
            fileArtifact.setName(createFileName(name));
            entity = fileArtifact;
            break;
        case IResource.FOLDER:
            FolderArtifact folderArtifact = aef.createFolderArtifact();
            folderArtifact.setName(aef.createName(name));
            folderArtifact.setArtifacts(aef.createArtifacts(0));
            entity = folderArtifact;
            break;
        case IResource.PROJECT:
            Project project = aef.createProject();
            project.setName(aef.createName(name));
            project.setArtifacts(aef.createArtifacts(0));
            entity = project;
            break;
        default:
        case IResource.ROOT:
            Workspace workspace = aef.createWorkspace();
            workspace.setProjects(aef.createProjects(0));
            entity = workspace;
            break;
        }
        boolean isWorkspace = Matcher.match(ArtifactsEntityDescriptorEnum.Workspace, entity);
        if (!EntityUtils.isNull(child))
            entity.wGet(isWorkspace ? ArtifactsFeatureDescriptorEnum.projects
                    : ArtifactsFeatureDescriptorEnum.artifacts).wAdd(child);

        return fromResource.equals(toResource) ? entity
                : toArtifactsPath(fromResource, toResource.getParent(), entity);
    }

    public static IEntity toArtifactsPath(IJavaElement fromJavaElement, IJavaElement toJavaElement) {
        return toArtifactsPath(fromJavaElement, toJavaElement, NullEntity.instance);
    }

    public static IEntity toArtifactsPath(IJavaElement fromJavaElement, IJavaElement toJavaElement, IEntity child) {
        ArtifactsEntityFactory aef = ArtifactsEntityFactory.instance(RegistryConfigurations.RESOLVER);

        IEntity entity;
        String name = toJavaElement.getElementName();
        switch (toJavaElement.getElementType()) {
        case IJavaElement.COMPILATION_UNIT:
            FileArtifact fileArtifact = aef.createFileArtifact();
            fileArtifact.setName(createFileName(name));
            entity = fileArtifact;
            break;
        case IJavaElement.PACKAGE_FRAGMENT:
            if (name == IPackageFragment.DEFAULT_PACKAGE_NAME)
                return fromJavaElement.equals(toJavaElement) ? child
                        : toArtifactsPath(fromJavaElement, toJavaElement.getParent(), child);

            PackageArtifact packageArtifact = aef.createPackageArtifact();
            packageArtifact.setName(aef.createName(name));
            entity = packageArtifact;
            break;
        case IJavaElement.PACKAGE_FRAGMENT_ROOT:
            FolderArtifact folderArtifact = aef.createFolderArtifact();
            Metadata metadata = aef.createMetadata();
            metadata.setAttributes(aef.createAttributes(aef.createAttribute(AttributeEnum.source)));
            folderArtifact.setMetadata(metadata);
            folderArtifact.setName(aef.createName(name));
            entity = folderArtifact;
            break;
        case IJavaElement.JAVA_PROJECT:
            Project project = aef.createProject();
            project.setName(aef.createName(name));
            project.setNatures(aef.createNatures(aef.createNature("org.eclipse.jdt.core.javanature")));
            project.setArtifacts(aef.createArtifacts(0));
            entity = project;
            break;
        default:
        case IJavaElement.JAVA_MODEL:
            Workspace workspace = aef.createWorkspace();
            workspace.setProjects(aef.createProjects(0));
            entity = workspace;
            break;
        }
        boolean isWorkspace = Matcher.match(ArtifactsEntityDescriptorEnum.Workspace, entity);
        if (!EntityUtils.isNull(child))
            entity.wGet(isWorkspace ? ArtifactsFeatureDescriptorEnum.projects
                    : ArtifactsFeatureDescriptorEnum.artifacts).wAdd(child);

        return fromJavaElement.equals(toJavaElement) ? entity
                : toArtifactsPath(fromJavaElement, toJavaElement.getParent(), entity);
    }

    public static IEntity toArtifactsPath(IJavaElement fromJavaElement, IResource toResource) {
        ArtifactsEntityFactory aef = ArtifactsEntityFactory.instance(RegistryConfigurations.RESOLVER);

        Artifact child;
        if (toResource.getType() == IResource.FILE) {
            FileArtifact fileArtifact = aef.createFileArtifact();
            fileArtifact.setName(createFileName(toResource.getName()));
            child = fileArtifact;
        } else {
            FolderArtifact folderArtifact = aef.createFolderArtifact();
            folderArtifact.setName(aef.createName(toResource.getName()));
            child = folderArtifact;
        }

        return toArtifactsPath(fromJavaElement, JavaCore.create(toResource.getParent()), child);
    }

    public static IEntity getArtifacts(IEntity artifact) {
        ArtifactsEntityFactory aef = ArtifactsEntityFactory.instance(RegistryConfigurations.RESOLVER);
        IEntity children = BindingManagerFactory.instance.createTuple();

        if (Matcher.match(ArtifactsEntityDescriptorEnum.Workspace, artifact)) {
            IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
            for (IProject project : workspaceRoot.getProjects()) {
                Project projectArtifact = aef.createProject();
                projectArtifact.setName(aef.createName(project.getName()));
                projectArtifact.setArtifacts(aef.createArtifacts(0));
                children.wAdd(projectArtifact);
            }
        } else {
            try {
                IBindingManager bindings = BindingManagerFactory.instance.createBindingManager();
                bindPath(artifact, bindings, false);
                IContainer container = (IContainer) (bindings.wIsSet("folder") ? bindings.wGetValue("folder")
                        : bindings.wGetValue("project"));
                IJavaElement javaContainer = JavaCore.create(container);
                if (javaContainer == null || javaContainer.getElementType() == IJavaElement.JAVA_PROJECT) {
                    for (IResource resource : container.members()) {
                        if (resource.getType() == IResource.FILE) {
                            appendFileArtifact(((IFile) resource).getName(), children);
                        } else {
                            FolderArtifact folderArtifact = aef.createFolderArtifact();
                            Metadata metadata = aef.createMetadata();
                            metadata.setAttributes(aef.createAttributes(aef.createAttribute(AttributeEnum.source)));
                            folderArtifact.setMetadata(metadata);
                            folderArtifact.setName(aef.createName(StringUtils.getFileName(resource.getName())));
                            folderArtifact.setArtifacts(aef.createArtifacts(0));
                            children.wAdd(folderArtifact);
                        }
                    }
                } else {
                    if (javaContainer.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
                        IPackageFragmentRoot fragmentRoot = (IPackageFragmentRoot) javaContainer;
                        if (fragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
                            for (IJavaElement element : fragmentRoot.getChildren()) {
                                if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
                                    if (element.getElementName() == IPackageFragment.DEFAULT_PACKAGE_NAME) {
                                        appendPackageFragmentChildren((IPackageFragment) element, children);
                                    } else {
                                        PackageArtifact packageArtifact = aef.createPackageArtifact();
                                        packageArtifact.setName(
                                                aef.createName(StringUtils.getFileName(element.getElementName())));
                                        packageArtifact.setArtifacts(aef.createArtifacts(0));
                                        children.wAdd(packageArtifact);
                                    }
                                }
                            }
                        }
                    } else // IJavaElement.PACKAGE_FRAGMENT
                        appendPackageFragmentChildren((IPackageFragment) javaContainer, children);

                }
            } catch (Exception e) {
            }
        }

        return children;
    }

    protected static void appendPackageFragmentChildren(IPackageFragment packageFragment, IEntity children)
            throws Exception {
        for (ICompilationUnit cu : packageFragment.getCompilationUnits())
            appendFileArtifact(cu.getElementName(), children);

        for (Object resource : packageFragment.getNonJavaResources())
            if (resource instanceof IFile)
                appendFileArtifact(((IFile) resource).getName(), children);
    }

    protected static void appendFileArtifact(String nameWithExtension, IEntity children) {
        ArtifactsEntityFactory aef = ArtifactsEntityFactory.instance(RegistryConfigurations.RESOLVER);

        FileArtifact fileArtifact = aef.createFileArtifact();
        fileArtifact.setName(createFileName(nameWithExtension));
        children.wAdd(fileArtifact);
    }

    protected static FileName createFileName(String nameWithExtension) {
        ArtifactsEntityFactory aef = ArtifactsEntityFactory.instance(RegistryConfigurations.RESOLVER);

        String fileName = StringUtils.stripFileExtension(nameWithExtension);
        String extension = StringUtils.getFileExtension(nameWithExtension);
        if (fileName.length() > 0)
            return aef.createNameWithExtension(aef.createName(fileName), aef.createExtension(extension));
        else
            return aef.createName('.' + extension);
    }

    public static IEntity getPersistenceKits() {
        IEntity persistenceKitIds = BindingManagerFactory.instance.createTuple();
        for (IPersistenceKit persistenceKit : ReflectionFactory.getPersistenceKits())
            persistenceKitIds.wAdd(BindingManagerFactory.instance
                    .createSpecificValue(ReflectionFactory.getPersistenceKit(persistenceKit.getId())));
        return persistenceKitIds;
    }

    public static IEntity getPersistenceKits(FileArtifact fileArtifact) {
        IEntity persistenceKitIds = BindingManagerFactory.instance.createTuple();
        IBindingManager bindings = BindingManagerFactory.instance.createBindingManager();
        bindPath(fileArtifact, bindings, false);
        if (bindings.wIsSet("persistenceKitId")) {
            persistenceKitIds.wAdd(BindingManagerFactory.instance.createSpecificValue(
                    ReflectionFactory.getPersistenceKit(bindings.wStringValue("persistenceKitId"))));
            return persistenceKitIds;
        } else
            return getPersistenceKits();
    }

    public static IEntity getContents(FileArtifact fileArtifact, String persistenceKitId) {
        IBindingManager bindings = BindingManagerFactory.instance.createBindingManager();
        bindPath(fileArtifact, bindings, false);
        IFile file = (IFile) bindings.wGetValue("file");

        final IPersistenceProvider pp = new IFilePersistenceProvider(file);
        final Resolver resolver = CommonsEntityFactory.instance.createResolver();
        final Content fragment = CommonsEntityAdapterFactory
                .createStageUpFragment(ArtifactsEntityDescriptorEnum.Content, resolver);

        try {
            fragment.wSet(0, ReflectionFactory.getPersistenceKit(persistenceKitId).readModel(pp));
        } catch (Exception e) {
        }
        return fragment;
    }

    public static void loadContents(IEntity rootArtifact, IBindingManager bindings) {
        try {
            if (!Matcher.match(ArtifactsEntityDescriptorEnum.Project, rootArtifact)
                    && !Matcher.match(ArtifactsEntityDescriptorEnum.Workspace, rootArtifact))
                rootArtifact = (IEntity) rootArtifact.wGetParent().wGetParent();
            bindPath(rootArtifact, bindings, false);
        } catch (ClassCastException e) {
        }
        LoadContentsVisitor visitor = new LoadContentsVisitor(bindings);
        visitor.visit(rootArtifact);
    }

    public static class AncestorOrSelfInSameLanguageReverseIterator extends CollectionIterator<IEntity> {
        @Override
        protected Iterable<?> getCollectionIterable(IEntity entity) {
            List<IEntity> ancestors = new ArrayList<IEntity>();
            ILanguageKit languageKit = entity.wGetLanguageKit();

            IEntityIterator<IEntity> iterator = IteratorFactory.ancestorOrSelfIterator();
            iterator.reset(entity);
            for (IEntity parent : iterator) {
                if (languageKit.equals(parent.wGetLanguageKit()))
                    ancestors.add(parent);
                else
                    break;
            }
            Collections.reverse(ancestors);
            return ancestors;
        }
    }
}