/*****************************************************************************
* Copyright (c) 2012 CEA LIST.
*
* 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:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
*****************************************************************************/
package org.eclipse.papyrus.customization.properties.generation.layout;
import java.util.List;
import org.eclipse.papyrus.customization.properties.generation.Activator;
import org.eclipse.papyrus.customization.properties.generation.generators.IGenerator;
import org.eclipse.papyrus.customization.properties.generation.generators.ProfileGenerator;
import org.eclipse.papyrus.views.properties.contexts.Context;
import org.eclipse.papyrus.views.properties.contexts.DataContextElement;
import org.eclipse.papyrus.views.properties.contexts.DataContextPackage;
import org.eclipse.papyrus.views.properties.contexts.DataContextRoot;
import org.eclipse.papyrus.views.properties.contexts.Property;
import org.eclipse.papyrus.views.properties.contexts.View;
import org.eclipse.papyrus.views.properties.environment.CompositeWidgetType;
import org.eclipse.papyrus.views.properties.environment.Environment;
import org.eclipse.papyrus.views.properties.environment.LayoutType;
import org.eclipse.papyrus.views.properties.environment.PropertyEditorType;
import org.eclipse.papyrus.views.properties.environment.Type;
import org.eclipse.papyrus.views.properties.runtime.ConfigurationManager;
import org.eclipse.papyrus.views.properties.ui.CompositeWidget;
import org.eclipse.papyrus.views.properties.ui.Layout;
import org.eclipse.papyrus.views.properties.ui.PropertyEditor;
import org.eclipse.papyrus.views.properties.ui.UiFactory;
import org.eclipse.papyrus.views.properties.ui.ValueAttribute;
import org.eclipse.papyrus.views.properties.util.PropertiesUtil;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.UMLPackage;
public class ProfileWithDatatypes extends StandardLayoutGenerator {
protected IGenerator generator;
@Override
protected void sortEditors(List<PropertyEditor> editors) {
for(PropertyEditor editor : editors) {
Category category = new TypeCategory(editor.getProperty());
getByCategory(category).add(editor);
if(editor.getWidgetType() == null) {
Activator.log.warn(String.format("Editor for property %s doesn't have a WidgetType", editor.getProperty().getName())); //$NON-NLS-1$
continue;
}
namespaces.add(editor.getWidgetType().getNamespace());
}
}
@Override
protected CompositeWidget layoutCategorizedEditors(Category category, List<PropertyEditor> editors) {
if(((TypeCategory)category).isDatatype) {
CompositeWidgetType compositeType = ConfigurationManager.instance.getDefaultCompositeType();
CompositeWidget container = UiFactory.eINSTANCE.createCompositeWidget();
container.setWidgetType(compositeType);
Layout layout = createLayout(category.getNumColumns());
container.setLayout(layout);
for(PropertyEditor editor : editors) {
CompositeWidget group = createDataTypeGroup(editor.getProperty());
PropertyEditor viewEditor = UiFactory.eINSTANCE.createPropertyEditor();
viewEditor.setWidgetType(getViewEditor());
viewEditor.setProperty(editor.getProperty());
ValueAttribute view = UiFactory.eINSTANCE.createValueAttribute();
view.setName("view");
view.setValue(getViewName(editor.getProperty()));
viewEditor.getAttributes().add(view);
group.getWidgets().add(viewEditor);
container.getWidgets().add(group);
}
return container;
}
return super.layoutCategorizedEditors(category, editors);
}
protected String getViewName(Property property) {
if(!(generator instanceof ProfileGenerator)) {
return "";
}
org.eclipse.uml2.uml.Property attribute = ((ProfileGenerator)generator).getAttribute(property);
Package nearestPackage = attribute.getType().getNearestPackage();
Package rootPackage = nearestPackage;
while(rootPackage.getNestingPackage() != null) {
rootPackage = rootPackage.getNestingPackage();
}
//TODO : We're assuming the rootPackage has the same name as the context...
//This layout generator is really only compatible with ProfileGenerator
return rootPackage.getName() + ":Single " + attribute.getType().getName();
}
protected Context findContext(Property property) {
DataContextElement element = property.getContextElement();
if(element instanceof DataContextRoot) {
//TODO : Add a container reference to Context
return (Context)element.eContainer();
}
return findContext(element);
}
protected Context findContext(DataContextElement element) {
DataContextPackage dataContextPackage = element.getPackage();
if(dataContextPackage instanceof DataContextRoot) {
return (Context)dataContextPackage.eContainer();
}
return findContext(dataContextPackage);
}
protected String getQualifiedName(View view) {
return view.getContext().getName() + ":" + view.getName();
}
protected CompositeWidget createDataTypeGroup(Property property) {
CompositeWidgetType groupType = getGroupComposite();
CompositeWidget group = UiFactory.eINSTANCE.createCompositeWidget();
group.setWidgetType(groupType);
ValueAttribute text = UiFactory.eINSTANCE.createValueAttribute();
text.setName("text");
text.setValue(PropertiesUtil.getLabel(property));
group.getAttributes().add(text);
Layout layout = createLayout(1);
group.setLayout(layout);
return group;
}
protected Layout createLayout(Integer columns) {
LayoutType propertiesLayoutType = ConfigurationManager.instance.getDefaultLayoutType();
Layout layout = UiFactory.eINSTANCE.createLayout();
ValueAttribute numColumns = UiFactory.eINSTANCE.createValueAttribute();
numColumns.setName("numColumns"); //$NON-NLS-1$
numColumns.setValue(columns.toString());
layout.getAttributes().add(numColumns);
layout.setLayoutType(propertiesLayoutType);
return layout;
}
protected CompositeWidgetType getGroupComposite() {
for(Environment environment : ConfigurationManager.instance.getPropertiesRoot().getEnvironments()) {
for(CompositeWidgetType widgetType : environment.getCompositeWidgetTypes()) {
if(widgetType.getNamespace() == null && widgetType.getWidgetClass().equals("Group")) {
return widgetType;
}
}
}
Activator.log.warn("Cannot find the Group composite type");
return ConfigurationManager.instance.getDefaultCompositeType();
}
protected PropertyEditorType getViewEditor() {
for(Environment environment : ConfigurationManager.instance.getPropertiesRoot().getEnvironments()) {
for(PropertyEditorType widgetType : environment.getPropertyEditorTypes()) {
if(widgetType.getNamespace() != null && "ppe".equals(widgetType.getNamespace().getName()) && widgetType.getWidgetClass().equals("ViewEditor")) {
return widgetType;
}
}
}
Activator.log.warn("Cannot find the Group composite type");
return ConfigurationManager.instance.getDefaultEditorType(Type.STRING, false);
}
@Override
public void setGenerator(IGenerator generator) {
this.generator = generator;
}
protected class TypeCategory extends Category {
protected boolean isDatatype;
public TypeCategory(Property property) {
super(property);
org.eclipse.uml2.uml.Property attribute = resolveProperty(property);
if(attribute != null) {
isDatatype = attribute.getType().eClass() == UMLPackage.eINSTANCE.getDataType();
}
}
protected org.eclipse.uml2.uml.Property resolveProperty(Property property) {
//TODO : We should not have to rely on the IGenerator to retrieve the property...
if(generator instanceof ProfileGenerator) {
ProfileGenerator profileGenerator = (ProfileGenerator)generator;
return profileGenerator.getAttribute(property);
}
return null;
}
@Override
public Integer getNumColumns() {
if(isDatatype) {
return 1;
}
return super.getNumColumns();
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + getOuterType().hashCode();
result = prime * result + (isDatatype ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(!super.equals(obj)) {
return false;
}
if(!(obj instanceof TypeCategory)) {
return false;
}
TypeCategory other = (TypeCategory)obj;
if(!getOuterType().equals(other.getOuterType())) {
return false;
}
if(isDatatype != other.isDatatype) {
return false;
}
return true;
}
@Override
public Integer getTypeIndex() {
if(isDatatype) {
return orderedTypes.length + 1;
}
return super.getTypeIndex();
}
private ProfileWithDatatypes getOuterType() {
return ProfileWithDatatypes.this;
}
}
@Override
public String getName() {
return "UML Profile with DataTypes";
}
}