blob: 52ce9092c964a4ed5bea3626e35b69c521d90a73 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* 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:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*/
package org.eclipse.osbp.infogrid.api;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.osbp.ecview.core.common.model.core.YCompare;
import org.eclipse.osbp.ecview.core.common.model.core.YConverter;
import org.eclipse.osbp.ecview.core.common.model.core.YField;
import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridColumn;
import org.eclipse.osbp.ecview.extension.grid.CxGridFactory;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridButtonRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridDateRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridImageRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridIndicatorRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridNumberRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridPriceRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridProgressBarRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridQuantityRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRendererFactory;
import org.eclipse.osbp.ecview.extension.model.converter.YConverterFactory;
import org.eclipse.osbp.ecview.extension.model.converter.YNumericToResourceConfig;
import org.eclipse.osbp.ecview.extension.model.converter.YNumericToResourceConverter;
import org.eclipse.osbp.ecview.extension.model.converter.YStringToResourceConfig;
import org.eclipse.osbp.ecview.extension.model.converter.YStringToResourceConverter;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridProperty;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSource;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceEQFilter;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceInput;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridCompare;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropButtonStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropDateStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropImageStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropIndicatorStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropNumberStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropPriceStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropProgressbarStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropQuantityStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleConfig;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleConfigNumericToResource;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleConfigStringToResource;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStylePackage;
import org.eclipse.osbp.runtime.common.types.IBundleSpace;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SingleECViewGridFactory implements IECViewGridFactory {
private static final Logger LOGGER = LoggerFactory
.getLogger(SingleECViewGridFactory.class);
private CxGridFactory gridFactory = CxGridFactory.eINSTANCE;
// make extendable by services later
private IECViewGridEditorFieldFactory editorFieldFactory = new ECViewGridEditorFieldFactory();
public SingleECViewGridFactory() {
}
@Override
public CxGrid createGrid(Class<?> inputType, CxGridSource gridSource) {
BundleContext bc = FrameworkUtil.getBundle(getClass())
.getBundleContext();
ServiceReference<IBundleSpace> bsRef = bc
.getServiceReference(IBundleSpace.class);
if (bsRef == null) {
LOGGER.error("No BundleSpace available.");
return gridFactory.createCxGrid();
}
IBundleSpace bundleSpace = bc.getService(bsRef);
Class<?> rootType = null;
try {
rootType = bundleSpace.forName(gridSource.getRootTypeFQN());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// TODO: check the case "rootType == null". Maybe use a default rootType
// to continue ...
bc.ungetService(bsRef);
CxGrid grid = gridFactory.createCxGrid();
grid.setId(GRID_ID);
grid.getProperties().put(GRIDSOURCE_ID, gridSource.getId());
grid.setEditorEnabled(isEditable(gridSource));
grid.setHeaderVisible(true);
grid.setCustomFilters(false);
grid.setFilteringVisible(true);
grid.setUseBeanService(!gridSource.getTags().contains(IECViewGridSourceDescriptor.PROP_MANUAL_BEANS));
grid.setColumnReorderingAllowed(true);
if (rootType != null) {
grid.setType(rootType);
grid.setTypeQualifiedName(rootType.getName());
for (CxGridProperty prop : gridSource.getProperties()) {
CxGridColumn column = gridFactory.createCxGridColumn();
column.setPropertyPath(prop.getDotPath());
column.setPropertyId(prop.getDotPath());
Class<?> propertyType = BeanProperties
.value(rootType, prop.getDotPath())
.getPropertyDescriptor().getPropertyType();
// editable
YField yEditorField = getEditorField(prop, propertyType);
column.setEditable(yEditorField != null);
column.setEditorField(yEditorField);
Pair pair = createRendererPair(prop, propertyType);
column.setRenderer(pair.renderer);
column.setConverter(pair.converter);
// column.setMaxWidthPixels(50);
grid.getColumns().add(column);
}
}
for (CxGridSourceInput input : gridSource.getInputs()) {
if (inputType.getName().equals(input.getInputTypeFQN())) {
for (CxGridSourceEQFilter filter : input.getFilters()) {
// take the filter value from the input
filter.getInputTypePropertyPath();
}
}
}
return grid;
}
/**
* Returns the editor field for the given propertyType.
*
* @param prop
* @param propertyType
* @return
*/
protected YField getEditorField(CxGridProperty prop, Class<?> propertyType) {
return editorFieldFactory.createEditorField(prop, propertyType);
}
protected boolean isEditable(CxGridSource gridSource) {
for (CxGridProperty prop : gridSource.getProperties()) {
if (prop.isEditable()) {
return true;
}
}
return false;
}
/**
* Creates a renderer for the given property.
*
* @param prop
* @param propertyType
* @return
*/
protected Pair createRendererPair(CxGridProperty prop, Class<?> propertyType) {
Pair pair = new Pair();
CxGridRendererFactory factory = CxGridRendererFactory.eINSTANCE;
if (prop.getStyle() == null) {
return createBadRenderer();
}
EClass styleClass = prop.getStyle().eClass();
switch (styleClass.getClassifierID()) {
case CxGridStylePackage.CX_GRID_PROP_BOOLEAN_STYLE:
pair.renderer = factory.createCxGridBooleanRenderer();
break;
case CxGridStylePackage.CX_GRID_PROP_DATE_STYLE: {
CxGridPropDateStyle style = (CxGridPropDateStyle) prop.getStyle();
CxGridDateRenderer renderer = factory.createCxGridDateRenderer();
renderer.setDateFormat(style.getDateFormat());
pair.renderer = renderer;
}
break;
case CxGridStylePackage.CX_GRID_PROP_NUMBER_STYLE: {
if (!isNumeric(propertyType)) {
return createBadRenderer();
}
CxGridPropNumberStyle style = (CxGridPropNumberStyle) prop
.getStyle();
CxGridNumberRenderer renderer = factory
.createCxGridNumberRenderer();
renderer.setNumberFormat(style.getNumberFormat());
pair.renderer = renderer;
}
break;
case CxGridStylePackage.CX_GRID_PROP_BUTTON_STYLE: {
CxGridPropButtonStyle style = (CxGridPropButtonStyle) prop
.getStyle();
CxGridButtonRenderer renderer = factory
.createCxGridButtonRenderer();
renderer.setEventTopic(style.getEventTopic());
pair.renderer = renderer;
}
break;
case CxGridStylePackage.CX_GRID_PROP_IMAGE_STYLE: {
CxGridPropImageStyle style = (CxGridPropImageStyle) prop.getStyle();
YConverter converter = toConverter(style.getConfigs());
CxGridImageRenderer renderer = factory.createCxGridImageRenderer();
renderer.setEventTopic(style.getEventTopic());
pair.renderer = renderer;
pair.converter = converter;
}
break;
case CxGridStylePackage.CX_GRID_PROP_HTML_STYLE:
pair.renderer = factory.createCxGridHtmlRenderer();
break;
case CxGridStylePackage.CX_GRID_PROP_PROGRESSBAR_STYLE: {
CxGridPropProgressbarStyle style = (CxGridPropProgressbarStyle) prop
.getStyle();
CxGridProgressBarRenderer renderer = factory
.createCxGridProgressBarRenderer();
renderer.setMaxValue(style.getMaxValue());
pair.renderer = renderer;
}
break;
case CxGridStylePackage.CX_GRID_PROP_INDICATOR_STYLE: {
CxGridPropIndicatorStyle style = (CxGridPropIndicatorStyle) prop
.getStyle();
CxGridIndicatorRenderer renderer = factory
.createCxGridIndicatorRenderer();
renderer.setGreenStarts(style.getGreenStarts());
renderer.setRedEnds(style.getRedEnds());
pair.renderer = renderer;
}
break;
case CxGridStylePackage.CX_GRID_PROP_SPARKLINE_STYLE:
pair.renderer = factory.createCxGridHtmlRenderer();
break;
case CxGridStylePackage.CX_GRID_PROP_TEXT_STYLE:
pair.renderer = factory.createCxGridHtmlRenderer();
break;
case CxGridStylePackage.CX_GRID_PROP_QUANTITY_STYLE: {
CxGridPropQuantityStyle style = (CxGridPropQuantityStyle) prop
.getStyle();
CxGridQuantityRenderer renderer = factory
.createCxGridQuantityRenderer();
renderer.setHtmlPattern(style.getHtmlPattern());
renderer.setNullRepresentation("");
renderer.setNumberFormat(style.getValueNumberFormat());
renderer.setUomPropertyPath(style.getUomPropertyDotPath());
renderer.setValuePropertyPath(style.getValuePropertyDotPath());
pair.renderer = renderer;
}
break;
case CxGridStylePackage.CX_GRID_PROP_PRICE_STYLE: {
CxGridPropPriceStyle style = (CxGridPropPriceStyle) prop.getStyle();
CxGridPriceRenderer renderer = factory.createCxGridPriceRenderer();
renderer.setHtmlPattern(style.getHtmlPattern());
renderer.setNullRepresentation("");
renderer.setNumberFormat(style.getValueNumberFormat());
renderer.setCurrencyPropertyPath(style.getCurrencyPropertyDotPath());
renderer.setValuePropertyPath(style.getValuePropertyDotPath());
pair.renderer = renderer;
}
break;
}
return pair;
}
protected boolean isNumeric(Class<?> propertyType) {
boolean result = Number.class.isAssignableFrom(propertyType);
if (!result) {
if (propertyType.isPrimitive() && propertyType != Boolean.TYPE
&& propertyType != Void.TYPE) {
result = true;
}
}
return result;
}
protected YConverter toConverter(EList<CxGridStyleConfig> configs) {
if (configs.isEmpty()) {
return null;
}
CxGridStyleConfig cxConfig = configs.get(0);
if (cxConfig instanceof CxGridStyleConfigStringToResource) {
List<YStringToResourceConfig> newConfigs = toStringToResourceConfig(configs);
YStringToResourceConverter converter = YConverterFactory.eINSTANCE
.createYStringToResourceConverter();
converter.getConfigs().addAll(newConfigs);
return converter;
} else if (cxConfig instanceof CxGridStyleConfigNumericToResource) {
List<YNumericToResourceConfig> newConfigs = toNumberToResourceConfig(configs);
YNumericToResourceConverter converter = YConverterFactory.eINSTANCE
.createYNumericToResourceConverter();
converter.getConfigs().addAll(newConfigs);
return converter;
}
return null;
}
private List<YNumericToResourceConfig> toNumberToResourceConfig(
EList<CxGridStyleConfig> configs) {
List<YNumericToResourceConfig> result = new ArrayList<>(configs.size());
for (CxGridStyleConfig config : configs) {
if (!(config instanceof CxGridStyleConfigNumericToResource)) {
LOGGER.warn("you mixed up different style configs!");
continue;
}
CxGridStyleConfigNumericToResource givenConfig = (CxGridStyleConfigNumericToResource) config;
YNumericToResourceConfig newConfig = YConverterFactory.eINSTANCE
.createYNumericToResourceConfig();
newConfig.setResourceThemePath(givenConfig.getResourceThemePath());
newConfig.setValue(givenConfig.getValue());
newConfig.setCompare(toGridCompare(givenConfig.getCompare()));
result.add(newConfig);
}
return result;
}
private YCompare toGridCompare(CxGridCompare compare) {
switch (compare) {
case EQUAL:
return YCompare.EQUAL;
case GREATER_EQUAL:
return YCompare.GREATER_EQUAL;
case GREATER_THAN:
return YCompare.GREATER_THAN;
case LOWER_EQUAL:
return YCompare.LOWER_EQUAL;
case LOWER_THAN:
return YCompare.LOWER_THAN;
case NOT_EQUAL:
return YCompare.NOT_EQUAL;
}
return null;
}
private List<YStringToResourceConfig> toStringToResourceConfig(
EList<CxGridStyleConfig> configs) {
List<YStringToResourceConfig> result = new ArrayList<>(configs.size());
for (CxGridStyleConfig config : configs) {
if (!(config instanceof CxGridStyleConfigStringToResource)) {
LOGGER.warn("you mixed up different style configs!");
continue;
}
CxGridStyleConfigStringToResource givenConfig = (CxGridStyleConfigStringToResource) config;
YStringToResourceConfig newConfig = YConverterFactory.eINSTANCE
.createYStringToResourceConfig();
newConfig.setResourceThemePath(givenConfig.getResourceThemePath());
newConfig.setValue(givenConfig.getValue());
newConfig.setCompare(toGridCompare(givenConfig.getCompare()));
result.add(newConfig);
}
return result;
}
protected Pair createBadRenderer() {
Pair pair = new Pair();
pair.renderer = CxGridRendererFactory.eINSTANCE
.createCxGridTextRenderer();
return pair;
}
protected static class Pair {
public CxGridRenderer renderer;
public YConverter converter;
}
}