Package org.locationtech.udig.project.internal.impl

Source Code of org.locationtech.udig.project.internal.impl.ProjectRegistryImpl

/**
* <copyright></copyright> $Id$
*/
package org.locationtech.udig.project.internal.impl;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.locationtech.udig.catalog.URLUtils;
import org.locationtech.udig.project.IProject;
import org.locationtech.udig.project.internal.Messages;
import org.locationtech.udig.project.internal.Project;
import org.locationtech.udig.project.internal.ProjectElement;
import org.locationtech.udig.project.internal.ProjectFactory;
import org.locationtech.udig.project.internal.ProjectPackage;
import org.locationtech.udig.project.internal.ProjectPlugin;
import org.locationtech.udig.project.internal.ProjectRegistry;
import org.locationtech.udig.ui.PlatformGIS;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Internal;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;

/**
* TODO Purpose of org.locationtech.udig.project.internal.impl
* <p>
* </p>
*
* @author Jesse
* @since 1.0.0
* @generated
*/
public class ProjectRegistryImpl extends EObjectImpl implements ProjectRegistry {
    /**
     * The cached value of the '{@link #getCurrentProject() <em>Current Project</em>}' reference.
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @see #getCurrentProject()
     * @generated
     * @ordered
     */
    protected Project currentProject;

    /**
     * The cached value of the '{@link #getProjects() <em>Projects</em>}' reference list. <!--
     * begin-user-doc --> <!-- end-user-doc -->
     *
     * @see #getProjects()
     * @generated NOT
     * @ordered
     */
    @SuppressWarnings("unchecked")
    protected List projects = null;

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    protected ProjectRegistryImpl() {
        super();
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    @Override
    protected EClass eStaticClass() {
        return ProjectPackage.Literals.PROJECT_REGISTRY;
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     *
     * @generated NOT
     */
    @SuppressWarnings("unchecked")
    public List<Project> getProjects() {
        if (projects == null) {
            projects = new EObjectResolvingEList(Project.class, this,
                    ProjectPackage.PROJECT_REGISTRY__PROJECTS);
        }

        for (Iterator<Project> iter = projects.iterator(); iter.hasNext();) {
            Project project = iter.next();
            if (project.eResource() == null) {
                iter.remove(); // delete this one its resource is missing
            }
        }
        return projects;
    }

    /**
     * @see org.locationtech.udig.project.internal.ProjectRegistry#getDefaultProject()
     */
    public Project getDefaultProject() {
        String projectName = Messages.ProjectRegistry_defaultName;
        String path = new File(Platform.getLocation().toString() + File.separatorChar + projectName)
                .getAbsolutePath();
        currentProject = getProject(path);
        return currentProject;
    }

    /**
     * @see org.locationtech.udig.project.internal.ProjectRegistry#getCurrentProject()
     * @uml.property name="currentProject"
     */
    public Project getCurrentProject() {
        Project p = getCurrentProjectGen();
        if (p == null && getProjects().size() > 0)
            p = getProjects().get(0);
        if (p == null)
            p = getDefaultProject();
        return p;
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    public Project getCurrentProjectGen() {
        if (currentProject != null && currentProject.eIsProxy()) {
            InternalEObject oldCurrentProject = (InternalEObject) currentProject;
            currentProject = (Project) eResolveProxy(oldCurrentProject);
            if (currentProject != oldCurrentProject) {
                if (eNotificationRequired())
                    eNotify(new ENotificationImpl(this, Notification.RESOLVE,
                            ProjectPackage.PROJECT_REGISTRY__CURRENT_PROJECT, oldCurrentProject,
                            currentProject));
            }
        }
        return currentProject;
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    public Project basicGetCurrentProject() {
        return currentProject;
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     * @generated
     */
    public void setCurrentProject(Project newCurrentProject) {
        Project oldCurrentProject = currentProject;
        currentProject = newCurrentProject;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET,
                    ProjectPackage.PROJECT_REGISTRY__CURRENT_PROJECT, oldCurrentProject,
                    currentProject));
    }

    @Override
    public NotificationChain eSetResource(Internal resource, NotificationChain notifications) {
        if (resource == null || resource.getResourceSet() != resourceSet || resourceSet == null)
            throw new AssertionError();
        return super.eSetResource(resource, notifications);
    }

    /**
     * <!-- begin-user-doc --> <!-- end-user-doc -->
     *
     * @generated NOT
     */
    public Project getProject(URI uri) {
        // There is a sporatic bug here. Remove this try/catch when it is fixed.
        try {
            if (findProject(uri) != null) {
                // already available!
                return findProject(uri);
            }

            URI projectURI = URI.createURI(uri.toString());

            final ProjectRegistry registry = getProjectRegistry();
            Resource registryResource = registry.eResource();
            if (registryResource == null) {
                System.out.println("Registery was unable to load"); //$NON-NLS-1$
                throw new Error(Messages.ProjectRegistryImpl_load_error);
            }

            URI registryURI = registryResource.getURI();
            projectURI.deresolve(registryURI, true, true, true);

            ResourceSet registeryResourceSet = registryResource.getResourceSet();
            Resource projectResource = registeryResourceSet.createResource(projectURI);
            try {
                projectResource.load(null);
            } catch (IOException e1) {
                // resource doesn't exist. That is ok.
            }

            Project incomingProject = null;
            if (projectResource.getContents().isEmpty()) {
                // new file being created!
                if (projectURI.isFile()) {
                    // check to see if it exists; we don't like empty existing files
                    File file = new File(projectURI.toFileString());
                    if (file.exists()) {
                        if (!file.delete())
                            throw new NullPointerException("Unable to load " + uri
                                    + " file was empty");
                    }
                }
                // creating a new project from the new project wizard
                incomingProject = createProject(uri, projectResource);

            } else {
                // Go through list of resources
                EList<EObject> contents = projectResource.getContents();
                for (EObject eObject : contents) {
                    if (eObject instanceof Project) {
                        incomingProject = (Project) eObject;
                        break;
                    }
                }
                if (incomingProject == null) {
                    // this project was not saved with a project file?
                    // (does it represent an individial map? we are not sure)
                    throw new NullPointerException("Unable to load " + uri
                            + " - does not contain a project");
                }
                //                if (incomingProject == null) {
                //                    incomingProject = createProject(uri, resource);
                //                    List<ProjectElement> eContents = incomingProject.getElementsInternal();
                //                    for( EObject eObject : contents ) {
                //                        if (eObject instanceof MapImpl) {
                //                            MapImpl tmpMap = (MapImpl) eObject;
                //                            eContents.add(tmpMap);
                //                        }
                //                    }
                //                }
            }

            final Project newProject = incomingProject;
            PlatformGIS.syncInDisplayThread(new Runnable() {
                public void run() {
                    try {
                        setCurrentProject(newProject);
                        registry.getProjects().add(newProject);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });

            return newProject;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            // System.err.println("GetProject URI: " +uri);
        }
        return null; // remove this too
    }

    private Project findProject(URI uri) {
        List<Project> projects = getProjects();
        for (Project project : projects) {
            if (isURIEqual(project.eResource().getURI(), uri))
                return project;
        }
        return null;
    }

    public static boolean isURIEqual(URI uri, URI uri2) {
        if (uri.equals(uri2))
            return true;

        String uriString = uri.toString();
        String uri2String = uri2.toString();
        uriString = replaceBackSlashes(uriString);
        uri2String = replaceBackSlashes(uri2String);

        uriString = uriString.replace("://", ":/"); //$NON-NLS-1$//$NON-NLS-2$
        uri2String = uri2String.replace("://", ":/"); //$NON-NLS-1$//$NON-NLS-2$
        return uriString.equals(uri2String);
    }

    private static String replaceBackSlashes(String uriString) {
        StringBuffer buffer = new StringBuffer(uriString.length());
        for (int i = 0; i < uriString.length(); i++) {
            char charAt = uriString.charAt(i);
            if (charAt == '\\')
                buffer.append('/');
            else {
                buffer.append(charAt);
            }
        }
        return buffer.toString();
    }

    @SuppressWarnings("unchecked")
    private Project createProject(URI uri, Resource resource) {
        Project tmpProject = ProjectFactory.eINSTANCE.createProject();
        String path = uri.toFileString();
        int start = path.indexOf(File.separator) != -1 ? path.lastIndexOf(File.separator) : 0;
        int end = path.indexOf('.') != -1 ? path.lastIndexOf('.') : path.length() - 1;
        tmpProject.setName(path.substring(start + 1, end));
        resource.getContents().add(tmpProject);
        resource.setModified(true);

        return tmpProject;
    }

    /**
     * Convert projectPath into a URI and call getProject( uri ).
     */
    public Project getProject(String projectPath) {
        URL url;
        if (projectPath.startsWith("file:")) { //$NON-NLS-1$
            try {
                url = new URL(projectPath); // actually already a URL!
            } catch (MalformedURLException e) {
                System.err.println("Unable to turn " + projectPath + " into a URL to load");
                return null; // not a project               
            }
        } else {
            File file = new File(projectPath);
            url = URLUtils.fileToURL(file);
            // projectPath = "file://" + projectPath; //$NON-NLS-1$
        }

        final String uriText = url.toExternalForm() + File.separatorChar
                + ProjectRegistry.PROJECT_FILE; //$NON-NLS-1$
        final URI uri = URI.createURI(uriText);

        Project project = getProject(uri);
        return project;
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public Object eGet(int featureID, boolean resolve, boolean coreType) {
        switch (featureID) {
        case ProjectPackage.PROJECT_REGISTRY__CURRENT_PROJECT:
            if (resolve)
                return getCurrentProject();
            return basicGetCurrentProject();
        case ProjectPackage.PROJECT_REGISTRY__PROJECTS:
            return getProjects();
        }
        return super.eGet(featureID, resolve, coreType);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @SuppressWarnings("unchecked")
    @Override
    public void eSet(int featureID, Object newValue) {
        switch (featureID) {
        case ProjectPackage.PROJECT_REGISTRY__CURRENT_PROJECT:
            setCurrentProject((Project) newValue);
            return;
        case ProjectPackage.PROJECT_REGISTRY__PROJECTS:
            getProjects().clear();
            getProjects().addAll((Collection<? extends Project>) newValue);
            return;
        }
        super.eSet(featureID, newValue);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public void eUnset(int featureID) {
        switch (featureID) {
        case ProjectPackage.PROJECT_REGISTRY__CURRENT_PROJECT:
            setCurrentProject((Project) null);
            return;
        case ProjectPackage.PROJECT_REGISTRY__PROJECTS:
            getProjects().clear();
            return;
        }
        super.eUnset(featureID);
    }

    /**
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public boolean eIsSet(int featureID) {
        switch (featureID) {
        case ProjectPackage.PROJECT_REGISTRY__CURRENT_PROJECT:
            return currentProject != null;
        case ProjectPackage.PROJECT_REGISTRY__PROJECTS:
            return projects != null && !projects.isEmpty();
        }
        return super.eIsSet(featureID);
    }

    /**
     * @see org.locationtech.udig.IProjectRegistry#getDefaultIProject()
     */
    public IProject getDefaultIProject() {
        return getDefaultProject();
    }

    /**
     * @see org.locationtech.udig.IProjectRegistry#getCurrentIProject()
     */
    public IProject getCurrentIProject() {
        return getCurrentProject();
    }

    /**
     * @see org.locationtech.udig.IProjectRegistry#setICurrentProject(org.locationtech.udig.IProject)
     */
    public void setICurrentProject(IProject value) {
        setCurrentProject((Project) value);
    }

    /**
     * @see org.locationtech.udig.IProjectRegistry#getIProject(java.lang.String)
     */
    public IProject getIProject(String projectPath) {
        return getProject(projectPath);
    }

    /**
     * @see org.locationtech.udig.IProjectRegistry#getIProjects()
     */
    @SuppressWarnings("unchecked")
    public List getIProjects() {
        return getProjects();
    }

    private static ResourceSetImpl resourceSet;

    private static ProjectRegistry projectRegistry;

    /**
     * Loads the project registry.
     *
     * @return the loaded project registry.
     */
    @SuppressWarnings("unchecked")
    private synchronized static ProjectRegistry load() {
        ProjectRegistry projectRegistry = null;
        try {

            IPath registrypath = Platform.getLocation().append(".projectRegistry"); //$NON-NLS-1$
            URI uri = URI.createURI("file://" + registrypath.toOSString()); //$NON-NLS-1$

            projectRegistry = backwardsCompatibility(projectRegistry, registrypath, uri);

            if (projectRegistry == null) {

                // Load the resource through the editing domain.
                resourceSet = new ResourceSetImpl();

                if (registrypath.toFile().exists()) {
                    Resource resource = resourceSet.getResource(uri, true);
                    resourceSet.eSetDeliver(false);
                    projectRegistry = (ProjectRegistry) resource.getContents().get(0);
                    if (projectRegistry == null) {
                        projectRegistry = ProjectFactory.eINSTANCE.createProjectRegistry();
                        resource.getContents().add(projectRegistry);
                    }
                } else {
                    Resource resource = resourceSet.createResource(uri);
                    if (resource == null)
                        throw new Exception("Unable to load or create ProjectRegistry resource"); //$NON-NLS-1$

                    projectRegistry = new ProjectRegistryImpl();
                    resource.getContents().add(projectRegistry);
                }
            }
        } catch (Exception exception) {
            ProjectPlugin.INSTANCE.log(exception);
        }
        if (projectRegistry == null)
            ProjectPlugin.log("Error getting project from resource"); //$NON-NLS-1$
        else {
            final ProjectRegistry registry = projectRegistry;
            projectRegistry.eAdapters().add(new AdapterImpl() {
                /**
                 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
                 */
                public void notifyChanged(Notification msg) {
                    if (msg.getFeatureID(ProjectRegistry.class) == ProjectPackage.PROJECT_REGISTRY__PROJECTS) {
                        registry.eResource().setModified(true);
                    }
                }
            });
        }
        resourceSet.eSetDeliver(false);
        return projectRegistry;
    }

    /**
     * @param projectRegistry
     * @param registrypath
     * @param uri
     * @return
     */
    private static ProjectRegistry backwardsCompatibility(ProjectRegistry projectRegistry,
            IPath registrypath, URI uri) {
        IPath oldregistrypath = ProjectPlugin.getPlugin().getStateLocation()
                .append("ProjectRegistry"); //$NON-NLS-1$
        URI olduri = URI.createURI("file://" + oldregistrypath.toOSString()); //$NON-NLS-1$

        if (oldregistrypath.toFile().exists()) {
            resourceSet = new ResourceSetImpl();
            Resource resource = resourceSet.getResource(olduri, true);
            resourceSet.eSetDeliver(false);
            projectRegistry = (ProjectRegistry) resource.getContents().get(0);

            if (projectRegistry != null) {
                resourceSet = new ResourceSetImpl();
                resource = resourceSet.createResource(uri);
                resource.getContents().add(projectRegistry);
                oldregistrypath.toFile().deleteOnExit();
            }
        }
        return projectRegistry;
    }

    /**
     * @see org.locationtech.udig.project.internal.ProjectFactory#getProjectRegistry()
     * @uml.property   name="projectRegistry"
     */
    public static ProjectRegistry getProjectRegistry() {
        synchronized (ProjectRegistry.class) {
            if (projectRegistry == null) {
                projectRegistry = load();
            }
            if (projectRegistry.eResource() == null
                    || projectRegistry.eResource().getResourceSet() != resourceSet
                    || resourceSet == null)
                throw new AssertionError();
        }
        return projectRegistry;
    }

    @Override
    public EList<Adapter> eAdapters() {
        return SynchronizedEList.create(super.eAdapters());
    }

} // ProjectRegistryImpl
TOP

Related Classes of org.locationtech.udig.project.internal.impl.ProjectRegistryImpl

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.