/******************************************************************************* * 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.graphical.editors.model.javamapping; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl.ContainmentUpdatingFeatureMapEntry; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.DeleteCommand; import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.IEditingDomainProvider; import org.eclipse.emf.edit.provider.WrapperItemProvider; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.swt.graphics.Image; import org.jboss.tools.smooks.configuration.SmooksConfigurationActivator; import org.jboss.tools.smooks.configuration.editors.GraphicsConstants; import org.jboss.tools.smooks.configuration.editors.utils.ProjectClassLoader; import org.jboss.tools.smooks.configuration.editors.IXMLStructuredObject; import org.jboss.tools.smooks.configuration.editors.utils.SmooksUIUtils; import org.jboss.tools.smooks.gef.model.AbstractSmooksGraphicalModel; import org.jboss.tools.smooks.gef.tree.model.TreeNodeConnection; import org.jboss.tools.smooks.graphical.editors.IGraphicalEditorPart; import org.jboss.tools.smooks.graphical.editors.model.AbstractResourceConfigChildNodeGraphModel; import org.jboss.tools.smooks.graphical.editors.model.freemarker.FreemarkerTemplateConnection; import org.jboss.tools.smooks.graphical.editors.model.freemarker.FreemarkerTemplateGraphicalModel; import org.jboss.tools.smooks.graphical.editors.model.freemarker.FreemarkerTemplateNodeGraphicalModel; import org.jboss.tools.smooks.graphical.editors.model.freemarker.FreemarkerTemplateXMLModel; import org.jboss.tools.smooks.graphical.editors.model.freemarker.IFreemarkerTemplateModel; import org.jboss.tools.smooks.graphical.editors.template.SmooksFreemarkerTemplateGraphicalEditor; import org.jboss.tools.smooks.model.javabean12.BeanType; import org.jboss.tools.smooks.model.javabean12.DecodeParamType; import org.jboss.tools.smooks.model.javabean12.ExpressionType; import org.jboss.tools.smooks.model.javabean12.Javabean12Factory; import org.jboss.tools.smooks.model.javabean12.Javabean12Package; import org.jboss.tools.smooks.model.javabean12.ValueType; import org.jboss.tools.smooks.model.javabean12.WiringType; import org.jboss.tools.smooks.templating.model.ModelBuilder; import org.jboss.tools.smooks.templating.template.TemplateBuilder; import org.jboss.tools.smooks.templating.template.ValueMapping; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * @author Dart * */ public class JavaBeanChildGraphModel extends AbstractResourceConfigChildNodeGraphModel implements JavaNode { private IGraphicalEditorPart editorPart; public JavaBeanChildGraphModel(Object data, ITreeContentProvider contentProvider, ILabelProvider labelProvider, IEditingDomainProvider domainProvider, IGraphicalEditorPart editorPart) { super(data, contentProvider, labelProvider, domainProvider); this.editorPart = editorPart; } /* * (non-Javadoc) * * @see * org.jboss.tools.smooks.gef.model.AbstractSmooksGraphicalModel#isLinkable * (java.lang.Class) */ @Override public boolean isLinkable(Class<?> connectionType) { if (connectionType == null) { return true; } if (TreeNodeConnection.class.isAssignableFrom(connectionType)) { Object data = this.getData(); data = AdapterFactoryEditingDomain.unwrap(data); if (SmooksUIUtils.getBeanIDRefFeature((EObject) data) != null) { return true; } } if (data instanceof org.jboss.tools.smooks.model.javabean12.ValueType || connectionType == FreemarkerTemplateConnection.class) { return true; } // if (connectionType == ValueBindingConnection.class) { // Object data = this.getData(); // data = AdapterFactoryEditingDomain.unwrap(data); // if (SmooksUIUtils.getSelectorFeature((EObject)data) != null) { // return true; // } // } return false; } protected boolean inJavaMapping() { if (SmooksFreemarkerTemplateGraphicalEditor.ID.equals(editorPart.getID())) { return false; } return true; } /* * (non-Javadoc) * * @seeorg.jboss.tools.smooks.graphical.editors.model. * AbstractResourceConfigChildNodeGraphModel * #canLinkWithSource(java.lang.Object) */ @Override public boolean canLinkWithSource(Object model) { // TODO Auto-generated method stub if (!inJavaMapping()) return false; return super.canLinkWithSource(model); } /* * (non-Javadoc) * * @seeorg.jboss.tools.smooks.graphical.editors.model. * AbstractResourceConfigChildNodeGraphModel * #canLinkWithTarget(java.lang.Object) */ @Override public boolean canLinkWithTarget(Object model) { AbstractSmooksGraphicalModel gm = (AbstractSmooksGraphicalModel) model; Object m = gm.getData(); Object obj = getData(); AbstractSmooksGraphicalModel pm = gm; while (pm != null && !(pm instanceof FreemarkerTemplateGraphicalModel)) { pm = pm.getParent(); } obj = AdapterFactoryEditingDomain.unwrap(obj); if (obj instanceof ValueType) { if (m instanceof IFreemarkerTemplateModel && pm instanceof FreemarkerTemplateGraphicalModel) { TemplateBuilder builder = ((FreemarkerTemplateGraphicalModel) pm).getTemplateBuilder(); if (((IFreemarkerTemplateModel) m).isHidden(builder)) { return false; } if (m instanceof FreemarkerTemplateXMLModel) { if (!((FreemarkerTemplateXMLModel) m).getXMLNodeChildren().isEmpty()) { return false; } } List<TreeNodeConnection> exsitingConnection = gm.getTargetConnections(); if (!exsitingConnection.isEmpty()) return false; for (Iterator<?> iterator = exsitingConnection.iterator(); iterator.hasNext();) { TreeNodeConnection treeNodeConnection = (TreeNodeConnection) iterator.next(); if (treeNodeConnection.getSourceNode() == this) { return false; } } AbstractSmooksGraphicalModel pgm = gm; while (pgm != null && pgm instanceof FreemarkerTemplateNodeGraphicalModel) { Object pd = ((FreemarkerTemplateNodeGraphicalModel) pgm).getData(); if (pd instanceof IFreemarkerTemplateModel) { IFreemarkerTemplateModel iFreemarkerTemplateModel = (IFreemarkerTemplateModel) pd; if (iFreemarkerTemplateModel.isManyOccurs() && pgm.getTargetConnections().isEmpty()) { Node modelNode = iFreemarkerTemplateModel.getModelNode(); if (modelNode instanceof Element) { return !ModelBuilder.getEnforceCollectionSubMappingRules((Element) modelNode); } else { return false; } } } pgm = pgm.getParent(); } return true; } } if (!inJavaMapping()) return false; return super.canLinkWithTarget(model); } /* * (non-Javadoc) * * @see org.jboss.tools.smooks.gef.tree.model.TreeNodeModel#getImage() */ @Override public Image getImage() { if (parentIsCollection()) { return SmooksConfigurationActivator.getDefault().getImageRegistry().get( GraphicsConstants.IMAGE_JAVA_COLLECTION); } if (parentIsArray()) { return SmooksConfigurationActivator.getDefault().getImageRegistry().get(GraphicsConstants.IMAGE_JAVA_ARRAY); } return super.getImage(); } public boolean parentIsCollection() { Object model = getData(); model = AdapterFactoryEditingDomain.unwrap(model); if (model instanceof EObject) { EObject parent = ((EObject) model).eContainer(); return SmooksUIUtils.isCollectionJavaGraphModel(parent); } return false; } public boolean parentIsArray() { Object model = getData(); model = AdapterFactoryEditingDomain.unwrap(model); if (model instanceof EObject) { EObject parent = ((EObject) model).eContainer(); return SmooksUIUtils.isArrayJavaGraphModel(parent); } return false; } /* * (non-Javadoc) * * @see org.jboss.tools.smooks.gef.tree.model.TreeNodeModel#getChildren() */ @Override public List<AbstractSmooksGraphicalModel> getChildren() { List<AbstractSmooksGraphicalModel> list = Collections.emptyList(); return list; } /* * (non-Javadoc) * * @seeorg.jboss.tools.smooks.graphical.editors.model. * AbstractResourceConfigChildNodeGraphModel * #addTargetConnection(org.jboss.tools * .smooks.gef.tree.model.TreeNodeConnection) */ @Override public void addTargetConnection(TreeNodeConnection connection, AbstractSmooksGraphicalModel sourceNode) { Object model = getData(); model = AdapterFactoryEditingDomain.unwrap(model); if (model instanceof ValueType) { EObject owner = (EObject) model; AbstractSmooksGraphicalModel targetGraphModel = connection.getSourceNode(); Object tm = targetGraphModel.getData(); if (tm instanceof IXMLStructuredObject) { CompoundCommand compoundCommand = new CompoundCommand(); String selector = SmooksUIUtils.generateFullPath((IXMLStructuredObject) tm, "/"); //$NON-NLS-1$ Command command = SetCommand.create(domainProvider.getEditingDomain(), owner, Javabean12Package.Literals.VALUE_TYPE__DATA, selector); compoundCommand.append(command); DecoderRecorder recoder = (DecoderRecorder) connection.getData(); String dataDecoder = getDataDecoder(connection); List<?> oldParameters = null; if(recoder != null){ dataDecoder = recoder.getDecoder(); oldParameters = recoder.getDecoderParameters(); } if(oldParameters != null){ Command addParamsCommand = AddCommand.create(domainProvider.getEditingDomain(), owner, Javabean12Package.Literals.VALUE_TYPE__DECODE_PARAM, oldParameters); compoundCommand.append(addParamsCommand); } else { // If the target is an Enum type, we want to configure the decode parameters... Class<?> targetType = getJavaType(); if(targetType.isEnum()) { if(dataDecoder == null) { dataDecoder = "Enum"; //$NON-NLS-1$ } compoundCommand.append(_newEnumDecodeParamSet(targetType, (ValueType) model)); } } if (dataDecoder != null) { Command decoderSetCommand = SetCommand.create(domainProvider.getEditingDomain(), owner, Javabean12Package.Literals.VALUE_TYPE__DECODER, dataDecoder); compoundCommand.append(decoderSetCommand); } domainProvider.getEditingDomain().getCommandStack().execute(compoundCommand); if (this.targetConnections.indexOf(connection) == -1) { this.targetConnections.add(connection); support.firePropertyChange(PRO_ADD_TARGET_CONNECTION, null, connection); } } } else { super.addTargetConnection(connection, sourceNode); } } public void newEnumDecodeParamSet(Class<?> enumType, ValueType valueType) { Command compoundCommand = _newEnumDecodeParamSet(enumType, valueType); domainProvider.getEditingDomain().getCommandStack().execute(compoundCommand); } private Command _newEnumDecodeParamSet(Class<?> enumType, ValueType valueType) { CompoundCommand compoundCommand = new CompoundCommand(); Field[] enumFields = enumType.getDeclaredFields(); compoundCommand.append(addDecodeParam("enumType", enumType.getName(), valueType)); //$NON-NLS-1$ for(Field enumField : enumFields) { if(enumField.isEnumConstant()) { compoundCommand.append(addDecodeParam(enumField.getName(), enumField.getName(), valueType)); } } return compoundCommand; } public Command addDecodeParam(String paramName, String paramValue, ValueType valueType) { DecodeParamType paramType = Javabean12Factory.eINSTANCE.createDecodeParamType(); paramType.setName(paramName); paramType.setValue(paramValue); return AddCommand.create(domainProvider.getEditingDomain(), valueType, Javabean12Package.Literals.VALUE_TYPE__DECODE_PARAM, paramType); } protected String getDataDecoder(TreeNodeConnection connection) { Object data = getData(); data = AdapterFactoryEditingDomain.unwrap(data); if(((ValueType)data).getDecoder() != null) return null; return SmooksUIUtils.getDefualtDecoder((ValueType)data); } /* * (non-Javadoc) * * @seeorg.jboss.tools.smooks.graphical.editors.model. * AbstractResourceConfigChildNodeGraphModel * #removeTargetConnection(org.jboss * .tools.smooks.gef.tree.model.TreeNodeConnection) */ @Override public void removeTargetConnection(TreeNodeConnection connection) { Object model = getData(); model = AdapterFactoryEditingDomain.unwrap(model); if (model instanceof ValueType) { EObject owner = (EObject) model; DecoderRecorder recorder = new DecoderRecorder(); CompoundCommand compoundCommand = new CompoundCommand(); Command deleteDataCommand = SetCommand.create(domainProvider.getEditingDomain(), owner, Javabean12Package.Literals.VALUE_TYPE__DATA, null); compoundCommand.append(deleteDataCommand); String decoder = ((ValueType)model).getDecoder(); if(decoder != null){ Command deleteDecoderCommand = SetCommand.create(domainProvider.getEditingDomain(), owner, Javabean12Package.Literals.VALUE_TYPE__DECODER, null); compoundCommand.append(deleteDecoderCommand); recorder.setDecoder( decoder); } if(!((ValueType)model).getDecodeParam().isEmpty()){ List<DecodeParamType> tempList = new ArrayList<DecodeParamType>(); tempList.addAll(((ValueType)model).getDecodeParam()); recorder.setDecoderParameters(tempList); Command remvoeParameterCommand = DeleteCommand.create(domainProvider.getEditingDomain(), ((ValueType)model).getDecodeParam()); compoundCommand.append(remvoeParameterCommand); } domainProvider.getEditingDomain().getCommandStack().execute(compoundCommand); connection.setData(recorder); if (this.targetConnections.indexOf(connection) != -1) { this.targetConnections.remove(connection); support.firePropertyChange(PRO_REMOVE_TARGET_CONNECTION, connection, null); } } else { super.removeTargetConnection(connection); } } /* * (non-Javadoc) * * @see org.jboss.tools.smooks.gef.tree.model.TreeNodeModel#getText() */ @Override public String getText() { int index = this.getParent().getChildrenWithoutDynamic().indexOf(this); if (parentIsArray() && index == 0) { return Messages.JavaBeanChildGraphModel_Array_Entry; } if (parentIsCollection() && index == 0) { return Messages.JavaBeanChildGraphModel_Collection_Entry; } return super.getText(); } private class DecoderRecorder{ private String decoder=null; private List<?> decoderParameters = null; /** * @return the decoder */ public String getDecoder() { return decoder; } /** * @param decoder the decoder to set */ public void setDecoder(String decoder) { this.decoder = decoder; } /** * @return the decoderParameters */ public List<?> getDecoderParameters() { return decoderParameters; } /** * @param decoderParameters the decoderParameters to set */ public void setDecoderParameters(List<?> decoderParameters) { this.decoderParameters = decoderParameters; } } public Class<?> getJavaType() { if(getData() instanceof WrapperItemProvider) { WrapperItemProvider sourceData = (WrapperItemProvider) getData(); Object binding = ((ContainmentUpdatingFeatureMapEntry)sourceData.getValue()).getValue(); if(binding instanceof ValueType) { return getPropertyType(getParentBean(), ((ValueType)binding).getProperty()); } else if(binding instanceof WiringType) { return getPropertyType(getParentBean(), ((WiringType)binding).getProperty()); } else if(binding instanceof ExpressionType) { return getPropertyType(getParentBean(), ((ExpressionType)binding).getProperty()); } } throw new IllegalStateException(Messages.JavaBeanChildGraphModel_Error); } public BeanType getParentBean() { if(getData() instanceof WrapperItemProvider) { WrapperItemProvider sourceData = (WrapperItemProvider) getData(); return (BeanType) sourceData.getOwner(); } throw new IllegalStateException(Messages.JavaBeanChildGraphModel_Error); } public Object getBindingTypeObj() { if(getData() instanceof WrapperItemProvider) { WrapperItemProvider sourceData = (WrapperItemProvider) getData(); return ((ContainmentUpdatingFeatureMapEntry) sourceData.getValue()).getValue(); } throw new IllegalStateException(Messages.JavaBeanChildGraphModel_Error); } /* (non-Javadoc) * @see org.jboss.tools.smooks.graphical.editors.model.AbstractResourceConfigGraphModel#addMappingTypeInfo(org.jboss.tools.smooks.templating.template.ValueMapping) */ @Override public void addMappingTypeInfo(ValueMapping mapping) { if(getData() instanceof WrapperItemProvider) { WrapperItemProvider sourceData = (WrapperItemProvider) getData(); Object binding = ((ContainmentUpdatingFeatureMapEntry)sourceData.getValue()).getValue(); if(binding instanceof ValueType) { mapping.setValueType(getJavaType()); if(mapping.getEncodeProperties() == null) { mapping.setEncodeProperties(getDecoderParams((ValueType) binding)); } } } } private Class<?> getPropertyType(BeanType bean, String targetProperty) { try { IJavaProject project = SmooksUIUtils.getJavaProject(bean); ProjectClassLoader classLoader = new ProjectClassLoader(project); Class<?> beanClass = classLoader.loadClass(bean.getClass_()); if(targetProperty != null && !targetProperty.trim().equals("")) { //$NON-NLS-1$ StringBuilder getterNameBuilder = new StringBuilder(); getterNameBuilder.append(targetProperty); getterNameBuilder.setCharAt(0, Character.toUpperCase(targetProperty.charAt(0))); getterNameBuilder.insert(0, "get"); //$NON-NLS-1$ try { Method getterMethod = beanClass.getMethod(getterNameBuilder.toString(), new Class[] {}); return getterMethod.getReturnType(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (JavaModelException e) { e.printStackTrace(); } return null; } public static Properties getDecoderParams(ValueType valueBinding) { Properties decodeParams = new Properties(); EList decodeParamsList = valueBinding.getDecodeParam(); for(int i = 0; i < decodeParamsList.size(); i++) { DecodeParamType decodeParamObj = (DecodeParamType) decodeParamsList.get(i); decodeParams.setProperty(decodeParamObj.getName(), decodeParamObj.getValue()); } return decodeParams; } }