org.eclipse.mylyn.reviews.connector.EmfTaskSchema.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mylyn.reviews.connector.EmfTaskSchema.java

Source

/*******************************************************************************
 * Copyright (c) 2012, 2013 Tasktop Technologies 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
 *
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.reviews.connector;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema;
import org.eclipse.mylyn.tasks.core.data.DefaultTaskSchema;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
import org.eclipse.mylyn.tasks.core.data.TaskData;

public abstract class EmfTaskSchema extends AbstractTaskSchema {

    public static final String TYPE_EMF_REFERENCE = "emf.reference"; //$NON-NLS-1$

    public static final String TYPE_EMF_GENERIC = "emf.generic"; //$NON-NLS-1$

    public static final String TYPE_EMF_UNSUPPORTED = "emf.unsupported"; //$NON-NLS-1$

    private final DefaultTaskSchema parent = DefaultTaskSchema.getInstance();

    public static class FieldFeature {
        Field parentField;

        EStructuralFeature feature;

        Flag[] flags;

        boolean readOnly;

        public FieldFeature(Field taskAttribute, EStructuralFeature emfFeature) {
            super();
            this.parentField = taskAttribute;
            this.feature = emfFeature;
        }

        public FieldFeature(Field taskAttribute, EStructuralFeature emfFeature, boolean readOnly, Flag... flags) {
            this(taskAttribute, emfFeature);
            this.readOnly = readOnly;
            this.flags = flags;
        }

        @Override
        public int hashCode() {
            // ignore
            return parentField.hashCode() * 31 + feature.hashCode();
        }

        @Override
        public boolean equals(Object other) {
            return other instanceof FieldFeature
                    && ObjectUtils.equals(parentField, ((FieldFeature) other).parentField)
                    && ObjectUtils.equals(feature, ((FieldFeature) other).feature);
        }
    }

    private final Map<EStructuralFeature, Field> fieldByFeature = new HashMap<EStructuralFeature, Field>();

    private final Map<String, EStructuralFeature> featureByTaskKey = new HashMap<String, EStructuralFeature>();

    private boolean keyFieldDefined;

    public void initialize() {
        for (FieldFeature fieldFeature : getSchemaPairs()) {
            if (fieldFeature.parentField.getKey() == parent.TASK_KEY.getKey()) {
                keyFieldDefined = true;
                break;
            }
        }
        for (FieldFeature fieldFeature : getSchemaPairs()) {
            createField(fieldFeature);
        }
        for (EClass schemaClass : getSchemaEClasses()) {
            for (EStructuralFeature feature : schemaClass.getEAllStructuralFeatures()) {
                //Don't replace explicitly mapped features.
                if (isSupported(feature) && fieldByFeature.get(feature) == null) {
                    createField(feature);
                }
            }
        }
    }

    @Override
    public void initialize(TaskData taskData) {
        if (!keyFieldDefined) {
            DefaultTaskSchema.getInstance().TASK_KEY.createAttribute(taskData.getRoot());
        }
        for (Field field : getFields()) {
            TaskAttribute attribute = field.createAttribute(taskData.getRoot());
            EStructuralFeature feature = getFeature(attribute.getId());
            if (feature instanceof EAttribute) {
                EAttribute emfAttribute = (EAttribute) feature;
                if (emfAttribute.getEAttributeType() instanceof EEnum) {
                    EEnum enumerator = (EEnum) emfAttribute.getEAttributeType();
                    for (EEnumLiteral literal : enumerator.getELiterals()) {
                        attribute.putOption(literal.getLiteral(), literal.getName());
                    }
                }
            }
        }
    }

    protected abstract EClass[] getSchemaEClasses();

    protected abstract FieldFeature[] getSchemaPairs();

    public String getTaskType(EStructuralFeature feature) {
        if (feature instanceof EReference) {
            return TYPE_EMF_REFERENCE;
        }
        int classifierID = feature.getEType().getClassifierID();
        switch (classifierID) {
        case EcorePackage.EBIG_DECIMAL:
            return TaskAttribute.TYPE_DOUBLE;
        case EcorePackage.EBIG_INTEGER:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.EBOOLEAN:
            return TaskAttribute.TYPE_BOOLEAN;
        case EcorePackage.EBOOLEAN_OBJECT:
            return TaskAttribute.TYPE_BOOLEAN;
        case EcorePackage.EBYTE:
            return TaskAttribute.TYPE_SHORT_TEXT;
        case EcorePackage.EBYTE_OBJECT:
            return TaskAttribute.TYPE_SHORT_TEXT;
        case EcorePackage.ECHAR:
            return TaskAttribute.TYPE_SHORT_TEXT;
        case EcorePackage.ECHARACTER_OBJECT:
            return TaskAttribute.TYPE_SHORT_TEXT;
        case EcorePackage.EDATE:
            return TaskAttribute.TYPE_DATE;
        case EcorePackage.EDOUBLE:
            return TaskAttribute.TYPE_DOUBLE;
        case EcorePackage.EDOUBLE_OBJECT:
            return TaskAttribute.TYPE_DOUBLE;
        case EcorePackage.EFLOAT:
            return TaskAttribute.TYPE_DOUBLE;
        case EcorePackage.EFLOAT_OBJECT:
            return TaskAttribute.TYPE_DOUBLE;
        case EcorePackage.EINT:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.EINTEGER_OBJECT:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.ELONG:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.ELONG_OBJECT:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.ESHORT:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.ESHORT_OBJECT:
            return TaskAttribute.TYPE_INTEGER;
        case EcorePackage.ESTRING:
            return TaskAttribute.TYPE_LONG_RICH_TEXT;
        case EcorePackage.EBYTE_ARRAY:
            return TYPE_EMF_GENERIC;
        case EcorePackage.EDIAGNOSTIC_CHAIN:
            return TYPE_EMF_UNSUPPORTED;
        default:
            return TYPE_EMF_UNSUPPORTED;
        }
    }

    public boolean isSupported(EStructuralFeature feature) {
        return !getTaskType(feature).startsWith("emf"); //$NON-NLS-1$
    }

    private void addEmfField(EStructuralFeature feature, Field field) {
        fieldByFeature.put(feature, field);
        featureByTaskKey.put(field.getKey(), feature);
    }

    protected Field createField(EStructuralFeature feature, Flag... flags) {
        String key = getKey(feature);
        String label = getLabel(feature);
        String type = getTaskType(feature);
        flags = (Flag[]) ArrayUtils.add(flags, Flag.ATTRIBUTE);
        Field field = createField(key, label, type, key, flags);
        addEmfField(feature, field);
        return field;
    }

    protected Field createField(FieldFeature fieldFeature) {
        Field parentField = fieldFeature.parentField;
        EStructuralFeature emfAttribute = fieldFeature.feature;
        String key = getKey(emfAttribute);
        FieldFactory factory = inheritFrom(parentField).key(key);
        if (fieldFeature.readOnly) {
            factory.addFlags(Flag.READ_ONLY);
        } else {
            factory.removeFlags(Flag.READ_ONLY);
        }
        Field field = factory.create();
        addEmfField(emfAttribute, field);
        featureByTaskKey.put(parentField.getKey(), emfAttribute);
        return field;
    }

    public String getKey(EStructuralFeature feature) {
        return "emf." + feature.getEContainingClass().getEPackage().getName() + "." //$NON-NLS-1$//$NON-NLS-2$
                + feature.getEContainingClass().getName().toLowerCase() + "." + feature.getName().toLowerCase(); //$NON-NLS-1$
    }

    public String getLabel(EStructuralFeature feature) {
        return WordUtils.capitalizeFully(
                StringUtils.join(StringUtils.splitByCharacterTypeCamelCase(feature.getName()), ' '));
    }

    /**
     * Finds the feature corresponding to the supplied task key. Features are matched on both attributes and matched
     * attributes.
     * 
     * @param feature
     * @return
     */
    public EStructuralFeature getFeature(String key) {
        return featureByTaskKey.get(key);
    }

    /**
     * Finds the field corresponding to the given structural feature.
     * 
     * @param feature
     * @return
     */
    public Field getFieldByFeature(EStructuralFeature feature) {
        return fieldByFeature.get(feature);
    }

    public TaskAttributeMapper getAttributeMapper(TaskRepository repository) {
        return new EmfAttributeMapper(this, repository);
    }
}