/******************************************************************************* * Copyright (c) 2008 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.smooks.editor.propertySections; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.edit.command.RemoveCommand; import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory; import org.jboss.tools.smooks.editor.ISmooksModelProvider; import org.jboss.tools.smooks.gef.model.AbstractSmooksGraphicalModel; import org.jboss.tools.smooks.gef.tree.model.TreeNodeConnection; import org.jboss.tools.smooks.graphical.editors.model.javamapping.JavaBeanChildGraphModel; import org.jboss.tools.smooks.model.javabean12.DecodeParamType; import org.jboss.tools.smooks.model.javabean12.Javabean12Package; import org.jboss.tools.smooks.model.javabean12.ValueType; import org.milyn.javabean.DataDecoder; import org.milyn.javabean.decoders.EnumDecoder; import org.milyn.javabean.decoders.IntegerDecoder; /** * @author Dart * */ public class ValueDecodeParamSection extends AbstractSmooksPropertySection { private Composite controlComposite; private TableViewer paramterViewer; private CCombo decoderCombo; boolean isEnumTarget; private TableColumn nameColumn; private TableColumn valueColumn; private static List<String> DECODERS = new ArrayList<String>(); static { Map<Class, Class<? extends DataDecoder>> map = DataDecoder.Factory.getInstalledDecoders(); Collection<Class<? extends DataDecoder>> decoders = map.values(); DECODERS.add(""); //$NON-NLS-1$ for (Iterator<Class<? extends DataDecoder>> iterator = decoders.iterator(); iterator.hasNext();) { Class<? extends DataDecoder> dataDecoderClass = iterator.next(); if (dataDecoderClass != null) { String name = dataDecoderClass.getSimpleName(); if (name.endsWith("Decoder")) { //$NON-NLS-1$ name = name.substring(0, name.length() - "Decoder".length()); //$NON-NLS-1$ } if (!DECODERS.contains(name)) { DECODERS.add(name); } } } Collections.sort(DECODERS); } /* * (non-Javadoc) * * @see * org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#createControls * (org.eclipse.swt.widgets.Composite, * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage) */ @Override public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) { super.createControls(parent, aTabbedPropertySheetPage); TabbedPropertySheetWidgetFactory factory = aTabbedPropertySheetPage.getWidgetFactory(); Section section = createRootSection(factory, parent); section.setText(Messages.ValueDecodeParamSection_SectionTitle); controlComposite = factory.createComposite(section, SWT.NONE); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; gridLayout.horizontalSpacing = 13; gridLayout.verticalSpacing = 20; controlComposite.setLayout(gridLayout); section.setClient(controlComposite); createDecoderCombo(factory, controlComposite); createDecodeParamViewer(factory, controlComposite); } private void createDecoderCombo(TabbedPropertySheetWidgetFactory factory, Composite parent) { factory.createLabel(controlComposite, Messages.ValueDecodeParamSection_DecoderLabel).setForeground(factory.getColors().getColor(IFormColors.TITLE)); decoderCombo = factory.createCCombo(parent, SWT.READ_ONLY); // decoderCombo.setEditable(false); GridData gd = new GridData(GridData.FILL_HORIZONTAL); decoderCombo.setLayoutData(gd); for (Iterator<?> iterator = DECODERS.iterator(); iterator.hasNext();) { String decoderName = (String) iterator.next(); decoderCombo.add(decoderName); } decoderCombo.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { changeDecoder(); } public void widgetDefaultSelected(SelectionEvent e) { } }); } private void changeDecoder() { ISmooksModelProvider provider = getSmooksModelProvider(); if (provider != null) { AdapterFactoryEditingDomain editingDomain = (AdapterFactoryEditingDomain) provider.getEditingDomain(); String newDecoder = decoderCombo.getText(); TreeNodeConnection lineModel = (TreeNodeConnection) getPresentSelectedGraphModel(); Object model = lineModel.getTargetNode().getData(); model = AdapterFactoryEditingDomain.unwrap(model); if (model != null && model instanceof ValueType) { String decoder = ((ValueType) model).getDecoder(); if (newDecoder.equals(decoder)) { // same decoder return; } CompoundCommand command = new CompoundCommand(); Command setCommand = SetCommand.create(editingDomain, model, Javabean12Package.Literals.VALUE_TYPE__DECODER, newDecoder); if (((ValueType) model).getDecodeParam().isEmpty()) { } else { Command removeCommand = RemoveCommand.create(editingDomain, ((ValueType) model).getDecodeParam()); command.append(setCommand); command.append(removeCommand); } if (command.isEmpty()) { editingDomain.getCommandStack().execute(setCommand); } else { editingDomain.getCommandStack().execute(command); } initDecodeParamViewer(); } } } private void createDecodeParamViewer(TabbedPropertySheetWidgetFactory factory, Composite sashForm) { GridData gd = new GridData(GridData.FILL_BOTH); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 2; Label label = factory.createLabel(sashForm, Messages.ValueDecodeParamSection_DecoderParamLabel); label.setLayoutData(gd); label.setForeground(factory.getColors().getColor(IFormColors.TITLE)); Composite viewerComposite = factory.createComposite(sashForm, SWT.NONE); gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; gd.heightHint = 150; viewerComposite.setLayoutData(gd); viewerComposite.setBackground(factory.getColors().getBorderColor()); // Composite viewerContianer = factory.createComposite(viewerComposite, SWT.NONE); // gd = new GridData(GridData.FILL_BOTH); // gd.heightHint = 150; // viewerContianer.setLayoutData(gd); FillLayout layout = new FillLayout(); layout.marginHeight = 1; layout.marginWidth = 1; viewerComposite.setLayout(layout); paramterViewer = new TableViewer(viewerComposite, SWT.FULL_SELECTION); paramterViewer.setContentProvider(new DecodeParamViewerContentProvider()); paramterViewer.setLabelProvider(new DecodeParamTypeLabelProvider()); paramterViewer.setFilters(new ViewerFilter[] { new DecodeParamTypeFilter() }); nameColumn = new TableColumn(paramterViewer.getTable(), SWT.NONE); valueColumn = new TableColumn(paramterViewer.getTable(), SWT.NONE); nameColumn.setText(Messages.ValueDecodeParamSection_ParamNameColumnText); valueColumn.setText(Messages.ValueDecodeParamSection_ParamValueColumnText); nameColumn.setWidth(150); valueColumn.setWidth(150); paramterViewer.setCellEditors(new CellEditor[] { new TextCellEditor(paramterViewer.getTable()), new TextCellEditor(paramterViewer.getTable()) }); paramterViewer.setColumnProperties(new String[] { "name", "value" }); //$NON-NLS-1$ //$NON-NLS-2$ paramterViewer.setCellModifier(new DecodeParamCellModifier()); paramterViewer.getTable().setHeaderVisible(true); paramterViewer.getTable().setLinesVisible(true); } private void initDecoderCombo() { decoderCombo.select(-1); TreeNodeConnection lineModel = (TreeNodeConnection) getPresentSelectedGraphModel(); AbstractSmooksGraphicalModel targetNode = lineModel.getTargetNode(); if(targetNode instanceof JavaBeanChildGraphModel) { JavaBeanChildGraphModel javaBeanChildGraphModel = (JavaBeanChildGraphModel)targetNode; Object bindingTypeObj = javaBeanChildGraphModel.getBindingTypeObj(); if (bindingTypeObj != null && bindingTypeObj instanceof ValueType) { Class<?> targetPropertyType = javaBeanChildGraphModel.getJavaType(); String decoderAlias = ((ValueType) bindingTypeObj).getDecoder(); if(decoderAlias != null) { // The decoder is configured... int index = DECODERS.indexOf(decoderAlias.trim()); decoderCombo.select(index); } else { // Try work out the decoder based on the target property type... DataDecoder decoder = DataDecoder.Factory.create(targetPropertyType); if(decoder.getClass().getPackage() == IntegerDecoder.class.getPackage()) { String decoderName = decoder.getClass().getSimpleName(); if(decoderName.endsWith("Decoder")) { //$NON-NLS-1$ decoderAlias = decoderName.substring(0, decoderName.length() - "Decoder".length()); //$NON-NLS-1$ int index = DECODERS.indexOf(decoderAlias); decoderCombo.select(index); } } } } } } private void initDecodeParamViewer() { paramterViewer.setInput("NULL"); //$NON-NLS-1$ TreeNodeConnection lineModel = (TreeNodeConnection) getPresentSelectedGraphModel(); AbstractSmooksGraphicalModel targetNode = lineModel.getTargetNode(); if(targetNode instanceof JavaBeanChildGraphModel) { JavaBeanChildGraphModel javaBeanChildGraphModel = (JavaBeanChildGraphModel)targetNode; Object bindingTypeObj = javaBeanChildGraphModel.getBindingTypeObj(); if (bindingTypeObj != null && bindingTypeObj instanceof ValueType) { Class<?> targetPropertyType = javaBeanChildGraphModel.getJavaType(); String decoderAlias = ((ValueType) bindingTypeObj).getDecoder(); DataDecoder decoder; DecodeParamMetaData[] decodeParamMetaData; if(decoderAlias != null) { // The decoder is configured... decoder = DataDecoder.Factory.create(decoderAlias); } else { // Try work out the decoder based on the target property type... decoder = DataDecoder.Factory.create(targetPropertyType); } if(decoder instanceof EnumDecoder) { // Get the enum values based on the targetPropertyType enum etc... isEnumTarget = true; paramterViewer.setInput(newEnumDecodeParamSet(targetPropertyType, (ValueType) bindingTypeObj, javaBeanChildGraphModel)); nameColumn.setText(Messages.ValueDecodeParamSection_EnumParamNameColumnText); valueColumn.setText(Messages.ValueDecodeParamSection_EnumParamValueColumnText); } else { isEnumTarget = false; nameColumn.setText(Messages.ValueDecodeParamSection_ParamNameColumnText); valueColumn.setText(Messages.ValueDecodeParamSection_ParamValueColumnText); decodeParamMetaData = DecodeParamMetaDataFactory.getDecodeParamMetaData(decoder.getClass()); if(decodeParamMetaData != null) { paramterViewer.setInput(newDecodeParam(decodeParamMetaData, ((ValueType) bindingTypeObj))); } } } } } private List<DecodeParam> newDecodeParam(DecodeParamMetaData[] decodeParamMetaData, ValueType valueType) { List<DecodeParam> list = new ArrayList<DecodeParam>(); for (int i = 0; i < decodeParamMetaData.length; i++) { DecodeParamMetaData decodeParamMD = decodeParamMetaData[i]; DecodeParam p = new DecodeParam(); DecodeParamType dp = findDecodeParamType(decodeParamMD.getName(), valueType); p.setName(decodeParamMD.getName()); if (dp != null) { String dpv = dp.getValue(); if (dpv != null) { dpv = dpv.trim(); } p.setValue(dpv); } else if(decodeParamMD.getDefaultVal() != null) { p.setValue(decodeParamMD.getDefaultVal()); } else if(decodeParamMD.isRequiresConfiguration()) { // TODO: We need to raise a warning... } list.add(p); } return list; } private List<DecodeParam> newEnumDecodeParamSet(Class<?> enumType, ValueType valueType, JavaBeanChildGraphModel enumValueModelNode) { List<DecodeParam> list = new ArrayList<DecodeParam>(); Properties configuredParams = JavaBeanChildGraphModel.getDecoderParams(valueType); if(!configuredParams.isEmpty()) { // Already configured... Set<Entry<Object, Object>> paramSet = configuredParams.entrySet(); for(Entry<Object, Object> param : paramSet) { String paramName = param.getKey().toString(); if(!paramName.equals("enumType")) { //$NON-NLS-1$ DecodeParam p = new DecodeParam(); p.setName(paramName); p.setValue(param.getValue().toString()); list.add(p); } } } else { Field[] enumFields = enumType.getDeclaredFields(); for(Field enumField : enumFields) { if(enumField.isEnumConstant()) { DecodeParam p = new DecodeParam(); p.setName(enumField.getName()); p.setValue(enumField.getName()); list.add(p); } } // And add them to the model... enumValueModelNode.newEnumDecodeParamSet(enumType, valueType); } return list; } private DecodeParamType findDecodeParamType(String name, ValueType valueType) { List<?> ps = valueType.getDecodeParam(); for (Iterator<?> iterator = ps.iterator(); iterator.hasNext();) { DecodeParamType dp = (DecodeParamType) iterator.next(); String dpn = dp.getName(); if (dpn != null) dpn = dpn.trim(); if (name.equals(dpn)) { return dp; } } return null; } protected void createDecodeParamGUIContents(Object model, ISmooksModelProvider provider, IEditorPart part, FormToolkit factory, Composite controlComposite) { // ModelPanelCreator creator = new ModelPanelCreator(); // model = AdapterFactoryEditingDomain.unwrap(model); // if (model != null && model instanceof EObject && provider != null && part != null) { // AdapterFactoryEditingDomain domain = (AdapterFactoryEditingDomain) provider.getEditingDomain(); // IItemPropertySource itemPropertySource = (IItemPropertySource) domain.getAdapterFactory().adapt(model, // IItemPropertySource.class); // if (itemPropertySource != null) { // creator // .createModelPanel((EObject) model, factory, controlComposite, itemPropertySource, provider, // part); // } // } } /* * (non-Javadoc) * * @see * org.jboss.tools.smooks.editor.propertySections.AbstractSmooksPropertySection * #refresh() */ @Override public void refresh() { super.refresh(); initDecoderCombo(); initDecodeParamViewer(); } private class DecodeParamViewerContentProvider implements IStructuredContentProvider { public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // TODO Auto-generated method stub } public void dispose() { // TODO Auto-generated method stub } public Object[] getElements(Object inputElement) { if (inputElement instanceof Collection<?>) { return ((Collection<?>) inputElement).toArray(); } return new Object[] {}; } } private class DecodeParam { String name; String value; /** * @return the name */ public String getName() { return name; } /** * @param name * the name to set */ public void setName(String name) { this.name = name; } /** * @return the value */ public String getValue() { return value; } /** * @param value * the value to set */ public void setValue(String value) { this.value = value; } } private class DecodeParamTypeLabelProvider extends LabelProvider implements ITableLabelProvider { public DecodeParamTypeLabelProvider() { } /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java * .lang.Object, int) */ public Image getColumnImage(Object element, int columnIndex) { // if (labelProvider != null && columnIndex == 0) { // return labelProvider.getImage(element); // } return null; } public String getColumnText(Object object, int columnIndex) { Object obj = AdapterFactoryEditingDomain.unwrap(object); if (columnIndex == 0) { // if (obj instanceof DecodeParamType) { // String name = ((DecodeParamType) obj).getName(); // if (name == null) // name = ""; //$NON-NLS-1$ // return name; // } if (obj instanceof DecodeParam) { String name = ((DecodeParam) obj).getName(); if (name == null) name = ""; //$NON-NLS-1$ return name; } } if (columnIndex == 1) { // if (obj instanceof DecodeParamType) { // String value = ((DecodeParamType) obj).getValue(); // if (value == null) // value = ""; //$NON-NLS-1$ // return value; // } if (obj instanceof DecodeParam) { String value = ((DecodeParam) obj).getValue(); if (value == null) value = ""; //$NON-NLS-1$ return value; } } return ""; //$NON-NLS-1$ } } private class DecodeParamTypeFilter extends ViewerFilter { /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers * .Viewer, java.lang.Object, java.lang.Object) */ @Override public boolean select(Viewer viewer, Object parentElement, Object element) { element = AdapterFactoryEditingDomain.unwrap(element); if (element instanceof DecodeParam) { return true; } return false; } } private class DecodeParamCellModifier implements ICellModifier { public void modify(Object element, String property, Object value) { if (element instanceof TableItem) { Object currentElement = ((TableItem) element).getData(); TreeNodeConnection lineModel = (TreeNodeConnection) getPresentSelectedGraphModel(); EditingDomain editingDomain = getSmooksModelProvider().getEditingDomain(); Object model = lineModel.getTargetNode().getData(); model = AdapterFactoryEditingDomain.unwrap(model); if (model != null && model instanceof ValueType && currentElement instanceof DecodeParam) { String pname = ((DecodeParam) currentElement).getName(); DecodeParamType paramType = findDecodeParamType(pname, (ValueType) model); Command command = null; if (!isEnumTarget && property.equals("value")) { //$NON-NLS-1$ if (value != null) { String svalue = ((String) value).trim(); if ("".equals(svalue)) { //$NON-NLS-1$ if (paramType != null) { command = RemoveCommand.create(editingDomain, paramType); } } else { // if param is empty , add it if (paramType == null) { AbstractSmooksGraphicalModel targetNode = lineModel.getTargetNode(); if(targetNode instanceof JavaBeanChildGraphModel) { command = ((JavaBeanChildGraphModel)targetNode).addDecodeParam(pname, (String) value, (ValueType) model); } } else { command = SetCommand.create(editingDomain, paramType, Javabean12Package.Literals.DECODE_PARAM_TYPE__VALUE, value); } } } if (command != null) { editingDomain.getCommandStack().execute(command); ((DecodeParam) currentElement).setValue((String) value); paramterViewer.update(currentElement, new String[] { property }); } } else if (isEnumTarget && property.equals("name")) { //$NON-NLS-1$ if (value != null) { String svalue = ((String) value).trim(); if ("".equals(svalue)) { //$NON-NLS-1$ // Can't blank it for an enum... ignore... } else { command = SetCommand.create(editingDomain, paramType, Javabean12Package.Literals.DECODE_PARAM_TYPE__NAME, value); editingDomain.getCommandStack().execute(command); ((DecodeParam) currentElement).setName((String) value); paramterViewer.update(currentElement, new String[] { property }); } } } } } } public Object getValue(Object element, String property) { element = AdapterFactoryEditingDomain.unwrap(element); if (!isEnumTarget && property.equals("value")) { //$NON-NLS-1$ if (element instanceof DecodeParam) { String name = ((DecodeParam) element).getValue(); if (name == null) name = ""; //$NON-NLS-1$ return name; } } else if (isEnumTarget && property.equals("name")) { //$NON-NLS-1$ if (element instanceof DecodeParam) { String name = ((DecodeParam) element).getName(); if (name == null) name = ""; //$NON-NLS-1$ return name; } } return null; } public boolean canModify(Object element, String property) { if (property.equals(isEnumTarget?"name":"value")) { //$NON-NLS-1$ //$NON-NLS-2$ if (element instanceof DecodeParam) { return true; } } return false; } } }