| /*******************************************************************************
|
| * Copyright (c) 2010, 2019 CEA LIST.
|
| *
|
| * All rights reserved. This program and the accompanying materials
|
| * are made available under the terms of the Eclipse Public License v2.0
|
| * which accompanies this distribution, and is available at
|
| * http://www.eclipse.org/legal/epl-v20.html
|
| *
|
| * Contributors:
|
| * Nicolas Bros (Mia-Software) - initial API and implementation
|
| * Nicolas Bros (Mia-Software) - Bug 338437 - compositeEditors extension point cannot be used to register user types
|
| * Nicolas Guyomar (Mia-Software) - Bug 339554 - org.eclipse.modisco.facet.widgets.celleditors API cleaning
|
| * Nicolas Bros (Mia-Software) - Bug 339855 - ModelCellEditor class should not be exposed
|
| * Gregoire Dupe (Mia-Software) - Bug 369987 - [Restructuring][Table] Switch to the new customization and facet framework
|
| *******************************************************************************/ |
| package org.eclipse.modisco.facet.widgets.celleditors.internal;
|
|
|
| import java.util.ArrayList;
|
| import java.util.List;
|
|
|
| import org.eclipse.core.runtime.IConfigurationElement;
|
| 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.EClassifier;
|
| import org.eclipse.emf.ecore.EDataType;
|
| import org.eclipse.emf.ecore.EObject;
|
| import org.eclipse.emf.ecore.EcorePackage;
|
| import org.eclipse.emf.ecore.resource.Resource;
|
| import org.eclipse.emf.ecore.resource.ResourceSet;
|
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
|
| import org.eclipse.emf.ecore.util.EcoreUtil;
|
| import org.eclipse.modisco.facet.util.core.Logger;
|
| import org.eclipse.modisco.facet.util.core.internal.exported.AbstractRegistry;
|
| import org.eclipse.modisco.facet.widgets.celleditors.ICellEditorsRegistry;
|
| import org.eclipse.modisco.facet.widgets.celleditors.IModelCellEditor;
|
| import org.eclipse.modisco.facet.widgets.celleditors.IModelCellEditorContainer;
|
| import org.eclipse.modisco.facet.widgets.celleditors.INaryFeatureCellEditor;
|
| import org.eclipse.modisco.facet.widgets.celleditors.modelCellEditor.AbstractModelCellEditor;
|
| import org.eclipse.modisco.facet.widgets.celleditors.modelCellEditor.BasicCellEditor;
|
| import org.eclipse.modisco.facet.widgets.celleditors.modelCellEditor.ModelCellEditorDeclarations;
|
| import org.eclipse.modisco.facet.widgets.celleditors.modelCellEditor.NaryFeatureCellEditor;
|
| import org.eclipse.modisco.facet.widgets.celleditors.modelCellEditor.UnaryReferenceCellEditor;
|
|
|
| /** Registry for the "loadingDepth" extension point */
|
| public class CellEditorsRegistry extends AbstractRegistry implements ICellEditorsRegistry {
|
|
|
| private static final String EXTENSION_POINT_NAMESPACE = "org.eclipse.modisco.facet.widgets.celleditors"; //$NON-NLS-1$
|
| private static final String EXTENSION_POINT_NAME = "celleditors"; //$NON-NLS-1$
|
|
|
| private static final String CELL_EDITORS_MODEL_ELEMENT = "cellEditorsModel"; //$NON-NLS-1$
|
| private static final String PATH_ATTRIBUTE = "path"; //$NON-NLS-1$
|
|
|
| /** A list of basic cell editors */
|
| private final List<ModelCellEditorContainer<BasicCellEditor>> basicCellEditors = new ArrayList<ModelCellEditorContainer<BasicCellEditor>>();
|
| /** A list of unary reference cell editors */
|
| private final List<ModelCellEditorContainer<UnaryReferenceCellEditor>> unaryReferenceCellEditors = new ArrayList<ModelCellEditorContainer<UnaryReferenceCellEditor>>();
|
| /** A list of n-ary reference cell editors */
|
| private final List<ModelCellEditorContainer<NaryFeatureCellEditor>> naryFeatureCellEditors = new ArrayList<ModelCellEditorContainer<NaryFeatureCellEditor>>();
|
|
|
| public CellEditorsRegistry() {
|
| initialize();
|
| }
|
|
|
| public List<IModelCellEditorContainer<? extends AbstractModelCellEditor>> getAllCellEditors() {
|
| List<IModelCellEditorContainer<? extends AbstractModelCellEditor>> allCellEditors = new ArrayList<IModelCellEditorContainer<? extends AbstractModelCellEditor>>();
|
| for (ModelCellEditorContainer<BasicCellEditor> basicCellEditor : this.basicCellEditors) {
|
| allCellEditors.add(basicCellEditor);
|
| }
|
| for (ModelCellEditorContainer<UnaryReferenceCellEditor> unaryReferenceCellEditor : this.unaryReferenceCellEditors) {
|
| allCellEditors.add(unaryReferenceCellEditor);
|
| }
|
| for (ModelCellEditorContainer<NaryFeatureCellEditor> naryReferenceCellEditor : this.naryFeatureCellEditors) {
|
| allCellEditors.add(naryReferenceCellEditor);
|
| }
|
| return allCellEditors;
|
| }
|
|
|
| /**
|
| * Returns a cell editor wrapper for the given type, or <code>null</code> if none was found.
|
| * Custom cell editors override the default ones (from
|
| * "org.eclipse.modisco.facet.widgets.celleditors").
|
| *
|
| * @param type
|
| * the type for which to get a cell editor wrapper
|
| * @param many
|
| * whether to get a cell editor to edit a single value or a list of values
|
| * @return the cell editor wrapper or <code>null</code> if none was found for the given type
|
| */
|
| public ModelCellEditor getCellEditorWrapperFor(final EClassifier type, final boolean many) {
|
| return getCellEditorWrapperFor(type, many, null);
|
| }
|
|
|
| /**
|
| * Returns a cell editor to edit a single value of the given type, or <code>null</code> if none
|
| * was found. Custom cell editors override the default ones (from
|
| * "org.eclipse.modisco.facet.widgets.celleditors").
|
| *
|
| * @param type
|
| * the type for which to get a cell editor
|
| * @return the cell editor or <code>null</code> if none was found for the given type
|
| */
|
| public IModelCellEditor getCellEditorFor(final EClassifier type) {
|
| ModelCellEditor cellEditorWrapper = getCellEditorWrapperFor(type, false);
|
| if (cellEditorWrapper != null) {
|
| return (IModelCellEditor) cellEditorWrapper.getCellEditorImplementation();
|
| }
|
| return null;
|
| }
|
|
|
| /**
|
| * Returns a cell editor wrapper to edit a list of values of the given type, or
|
| * <code>null</code> if none was found. Custom cell editors override the default ones (from
|
| * "org.eclipse.modisco.facet.widgets.celleditors").
|
| *
|
| * @param type
|
| * the type for which to get a cell editor
|
| * @return the cell editor wrapper or <code>null</code> if none was found for the given type
|
| */
|
| public INaryFeatureCellEditor getNaryCellEditorFor(final EClassifier type) {
|
| ModelCellEditor cellEditorWrapper = getCellEditorWrapperFor(type, true);
|
| if (cellEditorWrapper != null) {
|
| return (INaryFeatureCellEditor) cellEditorWrapper.getCellEditorImplementation();
|
| }
|
| return null;
|
| }
|
|
|
| public IModelCellEditor getCellEditorFor(final EClassifier type,
|
| final List<AbstractModelCellEditor> preferredCellEditors) {
|
| ModelCellEditor cellEditorWrapper = getCellEditorWrapperFor(type, false,
|
| preferredCellEditors);
|
| if (cellEditorWrapper != null) {
|
| return (IModelCellEditor) cellEditorWrapper.getCellEditorImplementation();
|
| }
|
| return null;
|
| }
|
|
|
| public INaryFeatureCellEditor getNaryCellEditorFor(final EClassifier type,
|
| final List<AbstractModelCellEditor> preferredCellEditors) {
|
| ModelCellEditor cellEditorWrapper = getCellEditorWrapperFor(type, true,
|
| preferredCellEditors);
|
| if (cellEditorWrapper != null) {
|
| return (INaryFeatureCellEditor) cellEditorWrapper.getCellEditorImplementation();
|
| }
|
| return null;
|
| }
|
|
|
| /**
|
| * Returns a cell editor for the given type, or <code>null</code> if none was found. Custom cell
|
| * editors override the default ones (from "org.eclipse.modisco.facet.widgets.celleditors").
|
| *
|
| * @param type
|
| * the type for which to get a cell editor
|
| * @param many
|
| * whether to get a cell editor to edit a single value or a list of values
|
| * @param preferredCellEditors
|
| * the cell editors that should be chosen in case of conflicts (several cell editors
|
| * defined for the same type)
|
| * @return the cell editor or <code>null</code> if none was found for the given type
|
| */
|
| public ModelCellEditor getCellEditorWrapperFor(final EClassifier type, final boolean many,
|
| final List<AbstractModelCellEditor> preferredCellEditors) {
|
|
|
| List<IModelCellEditorContainer<? extends AbstractModelCellEditor>> allCellEditorContainers = getAllCellEditors();
|
|
|
| List<ModelCellEditor> cellEditors = new ArrayList<ModelCellEditor>();
|
|
|
| for (IModelCellEditorContainer<? extends AbstractModelCellEditor> modelCellEditorContainer : allCellEditorContainers) {
|
| AbstractModelCellEditor modelCellEditor = modelCellEditorContainer.getModelCellEditor();
|
| if (isCellEditorForType(modelCellEditor, type, many)) {
|
| cellEditors.add(new ModelCellEditor(modelCellEditorContainer.getBundleName(),
|
| modelCellEditorContainer.getModelCellEditor()));
|
| }
|
| }
|
|
|
| ModelCellEditor selectedCellEditor = null;
|
|
|
| if (preferredCellEditors != null) {
|
| for (AbstractModelCellEditor preferredCellEditor : preferredCellEditors) {
|
| if (isCellEditorForType(preferredCellEditor, type, many)) {
|
| if (selectedCellEditor != null) {
|
| throw new IllegalArgumentException(
|
| "Several preferred cell editors are defined for type: " //$NON-NLS-1$
|
| + EcoreUtil.getURI(type));
|
| }
|
| selectedCellEditor = new ModelCellEditor("", preferredCellEditor); //$NON-NLS-1$
|
| }
|
| }
|
| }
|
|
|
| if (selectedCellEditor == null) {
|
| if (cellEditors.size() == 1) {
|
| selectedCellEditor = cellEditors.get(0);
|
| } else if (cellEditors.size() > 1) {
|
| boolean skippedDefault = false;
|
| for (ModelCellEditor cellEditor : cellEditors) {
|
| // lower priority for
|
| // org.eclipse.modisco.facet.widgets.celleditors.*
|
| if (cellEditor.getBundleName().startsWith(
|
| "org.eclipse.modisco.facet.widgets.celleditors")) { //$NON-NLS-1$
|
| if (skippedDefault) {
|
| Logger.logError(
|
| "Several default cell editors are defined in EMF Facet for type: " //$NON-NLS-1$
|
| + EcoreUtil.getURI(type), Activator.getDefault());
|
| selectedCellEditor = cellEditor;
|
| break;
|
| }
|
| skippedDefault = true;
|
| continue;
|
| }
|
| if (selectedCellEditor != null) {
|
| Logger.logWarning("Several cell editors are defined for type: " //$NON-NLS-1$
|
| + EcoreUtil.getURI(type), Activator.getDefault());
|
| break;
|
| }
|
| selectedCellEditor = cellEditor;
|
| }
|
| }
|
| }
|
|
|
| return selectedCellEditor;
|
| }
|
|
|
| public static boolean isCellEditorForType(final AbstractModelCellEditor modelCellEditor,
|
| final EClassifier type, final boolean many) {
|
| if (many != (modelCellEditor instanceof NaryFeatureCellEditor)) {
|
| return false;
|
| }
|
| return isSuperType(modelCellEditor.getCellType(), type);
|
| }
|
|
|
| private static boolean isSuperType(final EClassifier superType, final EClassifier subType) {
|
| if (superType == subType) {
|
| return true;
|
| }
|
|
|
| if (superType instanceof EClass && subType instanceof EClass) {
|
| // special case because isSuperTypeOf doesn't handle it
|
| if (superType == EcorePackage.eINSTANCE.getEObject()) {
|
| return true;
|
| }
|
|
|
| EClass superTypeEClass = (EClass) superType;
|
| EClass subTypeEClass = (EClass) subType;
|
| return superTypeEClass.isSuperTypeOf(subTypeEClass);
|
| }
|
|
|
| if (superType == EcorePackage.eINSTANCE.getEDataType() && subType instanceof EDataType) {
|
| // cf Bug 331539 - cell editor registered for type "EDataType"
|
| return true;
|
| }
|
|
|
| return false;
|
| }
|
|
|
| public List<ModelCellEditorContainer<BasicCellEditor>> getBasicCellEditors() {
|
| return this.basicCellEditors;
|
| }
|
|
|
| public List<ModelCellEditorContainer<UnaryReferenceCellEditor>> getUnaryReferenceCellEditors() {
|
| return this.unaryReferenceCellEditors;
|
| }
|
|
|
| public List<ModelCellEditorContainer<NaryFeatureCellEditor>> getNaryFeatureCellEditors() {
|
| return this.naryFeatureCellEditors;
|
| }
|
|
|
| @Override
|
| protected String getExtensionPointName() {
|
| return CellEditorsRegistry.EXTENSION_POINT_NAME;
|
| }
|
|
|
| @Override
|
| protected String getExtensionPointNamespace() {
|
| return CellEditorsRegistry.EXTENSION_POINT_NAMESPACE;
|
| }
|
|
|
| @Override
|
| protected void handleRootElement(final IConfigurationElement configurationElement) {
|
| final String name = configurationElement.getName();
|
| if (name.equalsIgnoreCase(CellEditorsRegistry.CELL_EDITORS_MODEL_ELEMENT)) {
|
| readModelElement(configurationElement);
|
| } else {
|
| logUnknownElement(configurationElement);
|
| }
|
| }
|
|
|
| /** Read a 'cellEditorsModel' element */
|
| private void readModelElement(final IConfigurationElement configurationElement) {
|
| final String path = configurationElement.getAttribute(CellEditorsRegistry.PATH_ATTRIBUTE);
|
| String bundleName = configurationElement.getContributor().getName();
|
| URI uri = URI.createURI("platform:/plugin/" //$NON-NLS-1$
|
| + configurationElement.getContributor().getName() + "/" + path); //$NON-NLS-1$
|
| ResourceSet resourceSet = new ResourceSetImpl();
|
| Resource resource = resourceSet.getResource(uri, true);
|
| if (resource != null) {
|
| EList<EObject> contents = resource.getContents();
|
| if (contents.size() == 1) {
|
| EObject eObject = contents.get(0);
|
| if (eObject instanceof ModelCellEditorDeclarations) {
|
| ModelCellEditorDeclarations modelCellEditors = (ModelCellEditorDeclarations) eObject;
|
| EList<AbstractModelCellEditor> allCellEditors = modelCellEditors
|
| .getModelCellEditors();
|
| for (AbstractModelCellEditor modelCellEditor : allCellEditors) {
|
| if (modelCellEditor instanceof BasicCellEditor) {
|
| BasicCellEditor basicCellEditor = (BasicCellEditor) modelCellEditor;
|
| ModelCellEditorContainer<BasicCellEditor> modelCellEditorContainer = new ModelCellEditorContainer<BasicCellEditor>();
|
| modelCellEditorContainer.setBundleName(bundleName);
|
| modelCellEditorContainer.setModelCellEditor(basicCellEditor);
|
| this.basicCellEditors.add(modelCellEditorContainer);
|
| } else if (modelCellEditor instanceof UnaryReferenceCellEditor) {
|
| UnaryReferenceCellEditor unaryReferenceCellEditor = (UnaryReferenceCellEditor) modelCellEditor;
|
| ModelCellEditorContainer<UnaryReferenceCellEditor> modelCellEditorContainer = new ModelCellEditorContainer<UnaryReferenceCellEditor>();
|
| modelCellEditorContainer.setBundleName(bundleName);
|
| modelCellEditorContainer.setModelCellEditor(unaryReferenceCellEditor);
|
| this.unaryReferenceCellEditors.add(modelCellEditorContainer);
|
| } else if (modelCellEditor instanceof NaryFeatureCellEditor) {
|
| NaryFeatureCellEditor naryFeatureCellEditor = (NaryFeatureCellEditor) modelCellEditor;
|
| ModelCellEditorContainer<NaryFeatureCellEditor> modelCellEditorContainer = new ModelCellEditorContainer<NaryFeatureCellEditor>();
|
| modelCellEditorContainer.setBundleName(bundleName);
|
| modelCellEditorContainer.setModelCellEditor(naryFeatureCellEditor);
|
| this.naryFeatureCellEditors.add(modelCellEditorContainer);
|
| } else {
|
| Logger.logError("Not handled: " //$NON-NLS-1$
|
| + modelCellEditor.getClass().getSimpleName(),
|
| Activator.getDefault());
|
| }
|
| }
|
| } else {
|
| Logger.logError("Root element must be of type " //$NON-NLS-1$
|
| + ModelCellEditorDeclarations.class.getSimpleName() + ": " + uri, //$NON-NLS-1$
|
| Activator.getDefault());
|
| }
|
| } else {
|
| Logger.logError("Resource should have one and only one root: " + uri, //$NON-NLS-1$
|
| Activator.getDefault());
|
| }
|
| } else {
|
| Logger.logError("Error reading resource: " + uri, Activator.getDefault()); //$NON-NLS-1$
|
| }
|
| }
|
| } |