/*******************************************************************************
* Copyright (c) 2008, 2012 Obeo.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.eef.codegen.core.initializer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.codegen.ecore.genmodel.GenAnnotation;
import org.eclipse.emf.codegen.ecore.genmodel.GenClass;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.eef.toolkits.Widget;
import org.eclipse.emf.eef.views.Category;
import org.eclipse.emf.eef.views.Container;
import org.eclipse.emf.eef.views.ElementEditor;
import org.eclipse.emf.eef.views.View;
import org.eclipse.emf.eef.views.ViewElement;
import org.eclipse.emf.eef.views.ViewsFactory;
import org.eclipse.emf.eef.views.ViewsRepository;
/**
* @author <a href="mailto:goulwen.lefur@obeo.fr">Goulwen Le Fur</a>
*/
public class ViewTransformer extends AbstractTransformer {
private Map<String, EObject> toolkits;
private Map<EObject, List<ViewElement>> workingResolvTemp;
private ViewsRepository repository;
/* ===== Constructor ===== */
public ViewTransformer(Map<String, EObject> toolkits) {
this.toolkits = toolkits;
workingResolvTemp = new HashMap<EObject, List<ViewElement>>();
}
/* ===== Getters/Setters ===== */
public Map<EObject, List<ViewElement>> getWorkingResolvTemp() {
return workingResolvTemp;
}
public void addElementToEObject(EObject source, ViewElement element) {
if (workingResolvTemp.get(source) != null)
workingResolvTemp.get(source).add(element);
else {
List<ViewElement> list = new UniqueEList<ViewElement>();
list.add(element);
workingResolvTemp.put(source, list);
}
}
/* ===== Transformation ===== */
public ViewsRepository genPackage2ViewsRepository(GenPackage genPackage, String repositoryKind) {
repository = ViewsFactory.eINSTANCE.createViewsRepository();
repository.getRepositoryKind().add("SWT");
repository.getRepositoryKind().add("Form");
repository.setName(genPackage.getEcorePackage().getName());
repository.setDocumentation("Views repository for " + genPackage.getEcorePackage().getName()
+ " GenPackage");
Category views = ViewsFactory.eINSTANCE.createCategory();
views.setName(genPackage.getEcorePackage().getName());
repository.getCategories().add(views);
for (GenClass genClass : genPackage.getGenClasses()) {
if (!genClass.getEcoreClass().isAbstract()) {
views.getViews().addAll(genClass2Views(genClass));
}
}
return repository;
}
public List<View> genClass2Views(GenClass genClass) {
List<View> result = new ArrayList<View>();
View view = ViewsFactory.eINSTANCE.createView();
view.setExplicit(true);
View additionalView = genClass2AdditionalView(genClass);
view.setName(genClass.getName());
Map<String, List<EStructuralFeature>> groups = genClassGroups(genClass);
for (String name : groups.keySet()) {
if (!name.equals("view")) {
Container container = ViewsFactory.eINSTANCE.createContainer();
container.setName(name);
container.setRepresentation(getWidget("Group"));
List<EStructuralFeature> features = groups.get(name);
for (EStructuralFeature structuralFeature : features) {
if (!structuralFeature.isDerived()) {
ElementEditor editor = eStructuralFeature2ViewElement(structuralFeature);
if (editor != null)
container.getElements().add(editor);
}
}
view.getElements().add(container);
}
}
if (groups.get("view") != null) {
List<EStructuralFeature> features = groups.get("view");
for (EStructuralFeature structuralFeature : features) {
if (!structuralFeature.isDerived()) {
ElementEditor editor = eStructuralFeature2ViewElement(structuralFeature);
if (editor != null)
view.getElements().add(editor);
}
}
}
result.add(view);
addElementToEObject(genClass.getEcoreClass(), view);
if (additionalView != null) {
result.add(additionalView);
addElementToEObject(genClass.getEcoreClass(), additionalView);
}
return result;
}
public View genClass2AdditionalView(GenClass genClass) {
View newView = null;
GenAnnotation genAnnotation = genClass.getGenAnnotation("component");
if (genAnnotation != null) {
newView = ViewsFactory.eINSTANCE.createCustomView();
String name = genAnnotation.getDetails().get("name");
if (name != null) {
newView.setName(genClass.getName() + name);
}
}
return newView;
}
public ElementEditor eStructuralFeature2ViewElement(EStructuralFeature feature) {
ElementEditor result = ViewsFactory.eINSTANCE.createElementEditor();
result.setName(feature.getName());
if (feature instanceof EAttribute) {
if (feature.isMany()) {
result.setRepresentation(getWidget("MultiValuedEditor"));
} else {
if (feature.getEType().getName().equals("EBoolean")
|| feature.getEType().getName().equals("EBool")
|| feature.getEType().getName().equalsIgnoreCase("Boolean")) {
result.setRepresentation(getWidget("Checkbox"));
} else if (EcorePackage.eINSTANCE.getEEnum().isInstance(feature.getEType())) {
result.setRepresentation(getWidget("EMFComboViewer"));
}
// FIXME: HACK
else if ("documentation".equals(feature.getName())) {
result.setRepresentation(getWidget("Textarea"));
} else {
result.setRepresentation(getWidget("Text"));
}
}
} else if (feature instanceof EReference) {
EReference reference = (EReference)feature;
if (reference.isContainment()) {
if (reference.isMany())
result.setRepresentation(getWidget("AdvancedTableComposition"));
else {
return null;
}
} else {
if (reference.isMany())
result.setRepresentation(getWidget("AdvancedReferencesTable"));
else
result.setRepresentation(getWidget("EObjectFlatComboViewer"));
}
}
addElementToEObject(feature, result);
return result;
}
/* ===== Widgets management ===== */
protected Widget getWidget(String name) {
if (name != null) {
for (String key : toolkits.keySet()) {
EObject toolkit = toolkits.get(key);
TreeIterator<EObject> iter = toolkit.eAllContents();
while (iter.hasNext()) {
EObject next = iter.next();
if (next instanceof Widget && name.equals(((Widget)next).getName()))
return (Widget)next;
}
}
}
return null;
}
/* ===== GenConstraint management ===== */
private Map<String, List<EStructuralFeature>> genClassGroups(GenClass genClass) {
Map<String, List<EStructuralFeature>> result = new HashMap<String, List<EStructuralFeature>>();
for (EStructuralFeature feature : genClass.getEcoreClass().getEAllStructuralFeatures()) {
if (isSignificant(feature) && getViewName(feature) == null) {
String groupConstraint = genConstraint(feature, "group");
if (groupConstraint != null) {
addToGroup(result, feature, groupConstraint);
} else {
// FIXME: HACK
String docConstraint = genConstraint(feature, "documentation");
if ("true".equals(docConstraint))
addToGroup(result, feature, "view");
else
addToGroup(result, feature, "properties");
}
}
}
return result;
}
/* ===== Misc utilities ===== */
private void addToGroup(Map<String, List<EStructuralFeature>> result, EStructuralFeature feature,
String genConstraint) {
if (result.get(genConstraint) != null)
result.get(genConstraint).add(feature);
else {
List<EStructuralFeature> list = new ArrayList<EStructuralFeature>();
list.add(feature);
result.put(genConstraint, list);
}
}
}