org.eclipse.xtext.ide.serializer.impl.EObjectDescriptionProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.xtext.ide.serializer.impl.EObjectDescriptionProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2017 TypeFox GmbH (http://www.typefox.io) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.xtext.ide.serializer.impl;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.ide.serializer.hooks.IEObjectDescriptionProvider;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;

/**
 * @author Moritz Eysholdt - Initial contribution and API
 */
public class EObjectDescriptionProvider implements IEObjectDescriptionProvider {

    protected static class SimpleNameDescription implements IEObjectDescription {

        private final EObject object;
        private final QualifiedName qualifiedName;
        private final QualifiedName simpleName;
        private final Map<String, String> userData;

        public SimpleNameDescription(QualifiedName qName, EObject resolvedObject, IEObjectDescription source) {
            this.simpleName = qName;
            this.object = resolvedObject;
            this.qualifiedName = source.getQualifiedName();
            Preconditions.checkArgument(!this.object.eIsProxy());
            Preconditions.checkNotNull(this.simpleName);
            Preconditions.checkNotNull(this.qualifiedName);
            Map<String, String> userData = null;
            for (final String key : source.getUserDataKeys()) {
                if (userData == null) {
                    userData = Maps.newHashMapWithExpectedSize(2);
                }
                userData.put(key, source.getUserData(key));
            }
            this.userData = userData;
        }

        @Override
        public EClass getEClass() {
            return object.eClass();
        }

        @Override
        public EObject getEObjectOrProxy() {
            return object;
        }

        @Override
        public URI getEObjectURI() {
            throw new UnsupportedOperationException();
        }

        @Override
        public QualifiedName getName() {
            return simpleName;
        }

        @Override
        public QualifiedName getQualifiedName() {
            return qualifiedName;
        }

        @Override
        public String getUserData(String key) {
            if (userData == null) {
                return null;
            }
            return userData.get(key);
        }

        @Override
        public String[] getUserDataKeys() {
            if (userData == null) {
                return new String[0];
            }
            return userData.keySet().toArray(new String[userData.size()]);
        }

        @Override
        public String toString() {
            StringBuilder result = new StringBuilder();
            result.append(IEObjectDescription.class.getSimpleName() + " " + qualifiedName);
            if (simpleName != null && !simpleName.equals(qualifiedName)) {
                result.append(" name:" + simpleName);
            }
            if (userData != null && !userData.isEmpty()) {
                List<String> items = Lists.newArrayList();
                for (Entry<String, String> e : userData.entrySet()) {
                    items.add(e.getKey() + ": " + e.getValue());
                }
                result.append(" userData=[" + Joiner.on(", ").join(items) + "]");
            }
            return result.toString();
        }

    }

    @Inject
    private IQualifiedNameProvider qualifiedNameProvider;

    @Inject
    private IResourceDescription.Manager resourceDescriptionManager;

    protected QualifiedName computeSimpleName(Multimap<EObject, IEObjectDescription> descs,
            IEObjectDescription desc) {
        QualifiedName name = desc.getQualifiedName();
        int segmentCount = name.getSegmentCount();
        if (segmentCount < 2) {
            return name;
        }
        EObject container = desc.getEObjectOrProxy().eContainer();
        while (container != null) {
            Collection<IEObjectDescription> candidates = descs.get(container);
            for (IEObjectDescription cand : candidates) {
                QualifiedName candName = cand.getQualifiedName();
                int candCount = candName.getSegmentCount();
                if (candCount < segmentCount && name.startsWith(candName)) {
                    return name.skipFirst(candCount);
                }
            }
            container = container.eContainer();
        }
        return name;
    }

    @Override
    public Iterable<IEObjectDescription> getEObjectDescriptions(Resource resource) {
        Multimap<EObject, IEObjectDescription> map = HashMultimap.create();
        IResourceDescription description = resourceDescriptionManager.getResourceDescription(resource);
        for (IEObjectDescription desc : description.getExportedObjects()) {
            EObject object = EcoreUtil.resolve(desc.getEObjectOrProxy(), resource);
            map.put(object, desc);
        }
        if (!resource.getContents().isEmpty()) {
            TreeIterator<EObject> it = EcoreUtil2.eAll(resource.getContents().get(0));
            while (it.hasNext()) {
                EObject next = it.next();
                if (map.containsKey(next)) {
                    continue;
                }
                QualifiedName name = qualifiedNameProvider.getFullyQualifiedName(next);
                if (name != null) {
                    IEObjectDescription desc = EObjectDescription.create(name, next);
                    map.put(next, desc);
                }
            }
        }
        List<IEObjectDescription> result = Lists.newArrayList();
        for (Map.Entry<EObject, IEObjectDescription> entry : map.entries()) {
            QualifiedName name = computeSimpleName(map, entry.getValue());
            SimpleNameDescription copy = new SimpleNameDescription(name, entry.getKey(), entry.getValue());
            result.add(copy);
        }
        return result;
    }

}