blob: 68dfc3e15f8df7609693fccb38fe4e46ec964b7f [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.ecview;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.osbp.ecview.core.common.context.ContextException;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.model.core.YBeanSlot;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.extension.model.extension.util.SimpleExtensionModelFactory;
import org.eclipse.osbp.ecview.core.util.emf.ModelUtil;
import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridPackage;
import org.eclipse.osbp.ecview.extension.grid.editparts.IGridEditpart;
import org.eclipse.osbp.ecview.extension.grid.util.CxGridUtil;
import org.eclipse.osbp.infogrid.api.AbstractGridSourceDescriptor;
import org.eclipse.osbp.infogrid.api.IECViewGridFactory;
import org.eclipse.osbp.infogrid.api.IECViewGridSourceDescriptor;
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.runtime.common.i18n.II18nService;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.VaadinRenderer;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService;
import org.eclipse.osbp.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.ui.CssLayout;
/**
* You need to pass the following properties during the creation of the
* descriptor.
* <p>
* <h2>services</h2>
* II18nService<br>
* E4EventBrokerAdapter<br>
* <h2>properties</h2>
* locale<br>
*
* <h2>Sample</h2>
*
* <pre>
* // render the Vaadin UI
* Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();
*
* // register services to be used
* Map&lt;String, Object&gt; services = new HashMap&lt;String, Object&gt;();
* services.put(
* org.eclipse.osbp.runtime.common.event.IEventBroker.class.getName(),
* new E4EventBrokerAdapter(e4EventBroker));
* services.put(II18nService.class.getName(), i18nService);
* properties.put(IViewContext.PARAM_SERVICES, services);
*/
public class ECViewGridSourceDescriptor extends AbstractGridSourceDescriptor
implements IECViewGridSourceDescriptor {
private static final Logger LOGGER = LoggerFactory
.getLogger(ECViewGridSourceDescriptor.class);
private static final String PROP_LOCALE = "locale";
private static final String BEAN_SLOT = "input";
private IECViewGridFactory factory;
private IViewContext viewContext;
private Locale locale;
private CxGrid cxGrid;
private SavedAdapter savedAdapter;
private EditorSavedStrategy editorSavedStrategy;
public ECViewGridSourceDescriptor(Class<?> inputType, CxGridSource source,
IECViewGridFactory factory) {
super(inputType, source);
this.factory = factory;
}
@Override
public Object getComponent() {
checkDisposed();
if (viewContext == null) {
try {
renderView();
} catch (ContextException e) {
throw new IllegalStateException(e);
}
}
return viewContext.getRootLayout();
}
protected void renderView() throws ContextException {
cxGrid = factory.createGrid(getInputType(), getSource());
SimpleExtensionModelFactory yFactory = new SimpleExtensionModelFactory();
YView yView = yFactory.createView();
YBeanSlot yBeanSlot = yFactory.createBeanSlot();
yBeanSlot.setName(BEAN_SLOT);
yBeanSlot.setValueType(Object.class);
yView.getBeanSlots().add(yBeanSlot);
yView.setContent(cxGrid);
IUserAccessService userAccessService;
// First alternative to get IUserAccessService via descriptor properties
@SuppressWarnings("unchecked")
Map<String, Object> services = (Map<String, Object>) properties
.get(IViewContext.PARAM_SERVICES);
if (services.containsKey(IUser.class.getName())) {
User user = (User) services.get(IUser.class.getName());
if (user != null) {
userAccessService = user.getUserAccessService();
cxGrid = CxGridUtil.setPermissions(userAccessService, cxGrid);
}
}
// Second alternative to get IUserAccessService via bundle context
// BundleContext bc = FrameworkUtil.getBundle(getClass())
// .getBundleContext();
// ServiceReference<IUserAccessService> ref = bc
// .getServiceReference(IUserAccessService.class);
// if (ref != null) {
// userAccessService = bc.getService(ref);
// cxGrid = CxGridUtil.setPermissions(userAccessService, cxGrid);
// }
CssLayout rootLayout = new CssLayout();
rootLayout.setSizeFull();
VaadinRenderer renderer = new VaadinRenderer();
viewContext = renderer.render(rootLayout, yView, properties);
viewContext.setLocale(locale);
updateSavedStrategy();
}
@Override
public void setInput(Object value) {
checkDisposed();
if (viewContext != null) {
viewContext.setBean(BEAN_SLOT, value);
IGridEditpart editpart = ModelUtil.findEditpart(cxGrid);
if (editpart != null) {
Map<String, Object> filterProps = createFilterMap(value);
editpart.setFilter(filterProps);
}
}
}
/**
* Creates a map containing the property as key and the filterValue as
* value.<br>
* These values will be added to the Grid as filter statements.
*
* @param value
* @return
*/
protected Map<String, Object> createFilterMap(Object value) {
Map<String, Object> filterProps = new HashMap<>();
if (value == null) {
return filterProps;
}
CxGridSourceInput input = findGridSourceInput(getSource());
if (input != null) {
for (CxGridSourceEQFilter filter : input.getFilters()) {
// the target property from the grids content.
String targetFilterProp = filter.getRootTypePropertyPath()
.getDotPath();
// the source property where the filter value should be used
// from
String sourceFilterProp = filter.getInputTypePropertyPath()
.getDotPath();
try {
Object sourceFilterValue = PropertyUtils.getNestedProperty(
value, sourceFilterProp);
filterProps.put(targetFilterProp, sourceFilterValue);
} catch (IllegalAccessException | InvocationTargetException
| NoSuchMethodException e) {
LOGGER.error("{}", e);
}
}
}
return filterProps;
}
private CxGridSourceInput findGridSourceInput(CxGridSource source) {
for (CxGridSourceInput input : source.getInputs()) {
if (getInputType().getName().equals(input.getInputTypeFQN())) {
return input;
}
}
return null;
}
@Override
public void setLocale(Locale locale) {
this.locale = locale;
}
@SuppressWarnings("unchecked")
@Override
public void setProperties(Map<String, Object> properties) {
super.setProperties(properties);
if (properties == null) {
LOGGER.warn("You should pass properties to ensure proper functionality!");
return;
}
if (!properties.containsKey(PROP_LOCALE)) {
LOGGER.warn("You should pass the locale.");
} else {
this.locale = (Locale) properties.get(PROP_LOCALE);
}
if (properties.containsKey(PROP_MANUAL_BEANS)) {
boolean useManualBeans = (boolean) properties
.get(PROP_MANUAL_BEANS);
if (useManualBeans) {
source.getTags().add(PROP_MANUAL_BEANS);
}
} else {
source.getTags().remove(PROP_MANUAL_BEANS);
}
if (!properties.containsKey(IViewContext.PARAM_SERVICES)) {
LOGGER.warn("You should pass some services. See JavaDoc of this class.");
} else {
Map<String, Object> services = (Map<String, Object>) properties
.get(IViewContext.PARAM_SERVICES);
if (!services.containsKey(II18nService.ID)) {
LOGGER.warn("You should pass the I18nService.");
}
if (!services
.containsKey("org.eclipse.osbp.runtime.common.event.IEventBroker")) {
LOGGER.warn("You should pass the org.eclipse.osbp.runtime.common.event.IEventBroker as an E4EventBrokerAdapter.");
}
}
}
@Override
protected void internalDispose() {
if (savedAdapter != null) {
cxGrid.eAdapters().remove(savedAdapter);
savedAdapter = null;
}
if (viewContext != null) {
viewContext.dispose();
viewContext = null;
}
if (properties != null) {
properties.clear();
properties = null;
}
factory = null;
}
@Override
public void setEditorSavedStrategy(EditorSavedStrategy strategy) {
this.editorSavedStrategy = strategy;
updateSavedStrategy();
}
protected void updateSavedStrategy() {
if (cxGrid == null) {
return;
}
if (editorSavedStrategy != null) {
if (savedAdapter == null) {
savedAdapter = new SavedAdapter();
}
if (!cxGrid.eAdapters().contains(savedAdapter)) {
cxGrid.eAdapters().add(savedAdapter);
}
} else {
if (savedAdapter != null) {
cxGrid.eAdapters().remove(savedAdapter);
}
}
}
@Override
public CxGrid getGrid() {
return cxGrid;
}
private class SavedAdapter extends AdapterImpl {
@Override
public void notifyChanged(Notification msg) {
if (msg.getFeature() == CxGridPackage.Literals.CX_GRID__EDITOR_SAVED) {
if (editorSavedStrategy != null) {
editorSavedStrategy.editorSaved(msg.getNewValue());
}
}
}
}
}