/*******************************************************************************
* 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.template;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.gef.EditPartFactory;
import org.jboss.tools.smooks.SmooksModelUtils;
import org.jboss.tools.smooks.configuration.editors.xml.AbstractXMLObject;
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.gef.tree.model.TreeNodeModel;
import org.jboss.tools.smooks.graphical.editors.ConnectionModelFactory;
import org.jboss.tools.smooks.graphical.editors.GraphicalModelFactory;
import org.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart;
import org.jboss.tools.smooks.graphical.editors.TaskTypeManager;
import org.jboss.tools.smooks.graphical.editors.autolayout.IAutoLayout;
import org.jboss.tools.smooks.graphical.editors.editparts.freemarker.FreemarkerAutoLayout;
import org.jboss.tools.smooks.graphical.editors.model.IValidatableModel;
import org.jboss.tools.smooks.graphical.editors.model.InputDataContianerModel;
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.IFreemarkerTemplateModel;
import org.jboss.tools.smooks.graphical.editors.process.TaskType;
import org.jboss.tools.smooks.model.freemarker.Freemarker;
import org.jboss.tools.smooks.templating.model.ModelBuilder;
import org.jboss.tools.smooks.templating.template.Mapping;
import org.jboss.tools.smooks.templating.template.TemplateBuilder;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* @author Dart
*
*/
public class SmooksFreemarkerTemplateGraphicalEditor extends SmooksGraphicalEditorPart {
public static final String ID = "__smooks_freemarker_template_graphical_editpart"; //$NON-NLS-1$
private IAutoLayout autoLayout = null;
public SmooksFreemarkerTemplateGraphicalEditor(ISmooksModelProvider provider) {
super(provider);
}
private boolean isConnectedDirectlyToInputTask() {
Object parentTask = getTaskType().getParent();
if(parentTask instanceof TaskType && ((TaskType) parentTask).getId().equals(TaskTypeManager.TASK_ID_INPUT)) {
return true;
}
return false;
}
/*
* (non-Javadoc)
*
* @seeorg.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#
* createEdtiPartFactory()
*/
@Override
protected EditPartFactory createEdtiPartFactory() {
FreemarkerTemplateEditFactory factory = new FreemarkerTemplateEditFactory();
return factory;
}
/* (non-Javadoc)
* @see org.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#createAllConnection(org.jboss.tools.smooks.gef.model.AbstractSmooksGraphicalModel)
*/
@Override
public Collection<TreeNodeConnection> createConnection(AbstractSmooksGraphicalModel model) {
if(isConnectedDirectlyToInputTask()) {
return createInputToTemplateConnections(model);
} else {
return super.createConnection(model);
}
}
private Collection<TreeNodeConnection> createInputToTemplateConnections(AbstractSmooksGraphicalModel model) {
List<AbstractSmooksGraphicalModel> mappingModels = root.getChildren();
// Should be 2 models in the mappingModels list. First should be the passed in model (the Input),
// while the second should be the FreeMarker (target) model.
if(mappingModels.size() == 2) {
AbstractSmooksGraphicalModel abstractSmooksGraphicalModel = mappingModels.get(0);
if(abstractSmooksGraphicalModel == model && abstractSmooksGraphicalModel instanceof InputDataContianerModel) {
InputDataContianerModel inputModel = (InputDataContianerModel) abstractSmooksGraphicalModel;
abstractSmooksGraphicalModel = mappingModels.get(1);
if(abstractSmooksGraphicalModel instanceof FreemarkerTemplateGraphicalModel) {
FreemarkerTemplateGraphicalModel freemarkerModel = (FreemarkerTemplateGraphicalModel) abstractSmooksGraphicalModel;
TemplateBuilder templateBuilder = freemarkerModel.getTemplateBuilder();
if (templateBuilder != null) {
List<Mapping> mappings = templateBuilder.getMappings();
List<TreeNodeConnection> connections = new ArrayList<TreeNodeConnection>();
for(Mapping mapping : mappings) {
TreeNodeModel connectionSource = inputModel.getModelNode(templateBuilder.resolveMappingSrcPath(mapping));
TreeNodeModel connectionTarget = freemarkerModel.getModelNode(mapping.getMappingNode());
if(connectionSource != null && connectionTarget != null) {
TreeNodeConnection connection = new FreemarkerTemplateConnection(connectionSource, connectionTarget);
connectionSource.getSourceConnections().add(connection);
connectionSource.fireConnectionChanged();
connectionTarget.getTargetConnections().add(connection);
connectionTarget.fireConnectionChanged();
connection.setData(mapping);
connections.add(connection);
}
}
return connections;
}
}
}
}
// Yes... not "nice" but
throw new RuntimeException("");
}
@Override
public void validateEnd(List<Diagnostic> diagnosticResult) {
cleanValidationMarker();
// validate freemarker model.Because the freemarker csv node
// model isn't EMF model so they need to validate separately
if (root == null)
return;
List<AbstractSmooksGraphicalModel> children = root.getChildren();
for (Iterator<?> iterator = children.iterator(); iterator.hasNext();) {
AbstractSmooksGraphicalModel abstractSmooksGraphicalModel = (AbstractSmooksGraphicalModel) iterator.next();
if (abstractSmooksGraphicalModel instanceof FreemarkerTemplateGraphicalModel) {
Object data = abstractSmooksGraphicalModel.getData();
data = AdapterFactoryEditingDomain.unwrap(data);
if (data instanceof Freemarker) {
String type = SmooksModelUtils.getTemplateType((Freemarker) data);
validateTemplate(type, abstractSmooksGraphicalModel);
}
}
}
}
protected void validateTemplate(String type, AbstractSmooksGraphicalModel templateGraphModel) {
List<AbstractSmooksGraphicalModel> templteContentsModels = templateGraphModel.getChildren();
validateTemplateContentsModel(type, templteContentsModels);
}
protected void validateTemplateContentsModel(String type, List<AbstractSmooksGraphicalModel> templteContentsModels) {
for (Iterator<?> iterator = templteContentsModels.iterator(); iterator.hasNext();) {
AbstractSmooksGraphicalModel abstractSmooksGraphicalModel = (AbstractSmooksGraphicalModel) iterator.next();
Object data = abstractSmooksGraphicalModel.getData();
if (data instanceof IFreemarkerTemplateModel) {
AbstractSmooksGraphicalModel requiredCollectionLinkParent = parentIsRequriedCollectionNode(abstractSmooksGraphicalModel);
if (requiredCollectionLinkParent != null && enforceCollectionSubMappingRules(abstractSmooksGraphicalModel)) {
AbstractXMLObject parentNode = (AbstractXMLObject) requiredCollectionLinkParent.getData();
abstractSmooksGraphicalModel.addMessage(Messages.SmooksFreemarkerTemplateGraphicalEditor_WarningMessage1 + parentNode.getName()
+ Messages.SmooksFreemarkerTemplateGraphicalEditor_WarningMessage2);
abstractSmooksGraphicalModel.setSeverity(IValidatableModel.ERROR);
}
if (isRequiredNode(abstractSmooksGraphicalModel)) {
abstractSmooksGraphicalModel.addMessage(Messages.SmooksFreemarkerTemplateGraphicalEditor_WarningMessage3);
abstractSmooksGraphicalModel.setSeverity(IValidatableModel.ERROR);
}
if (isRequiredCollectionNode(abstractSmooksGraphicalModel)) {
abstractSmooksGraphicalModel.addMessage(Messages.SmooksFreemarkerTemplateGraphicalEditor_WarningMessage4);
abstractSmooksGraphicalModel.setSeverity(IValidatableModel.ERROR);
}
}
validateTemplateContentsModel(type, abstractSmooksGraphicalModel.getChildren());
}
}
public static AbstractSmooksGraphicalModel parentIsRequriedCollectionNode(
AbstractSmooksGraphicalModel abstractSmooksGraphicalModel) {
AbstractSmooksGraphicalModel parent = abstractSmooksGraphicalModel.getParent();
Object data = abstractSmooksGraphicalModel.getData();
if (data instanceof IFreemarkerTemplateModel) {
if (isRequiredCollectionNode(parent)) {
return parent;
}
return parentIsRequriedCollectionNode(parent);
}
return null;
}
private boolean isRequiredNode(AbstractSmooksGraphicalModel abstractSmooksGraphicalModel) {
Object data = abstractSmooksGraphicalModel.getData();
AbstractSmooksGraphicalModel pm = abstractSmooksGraphicalModel;
while (pm != null && !(pm instanceof FreemarkerTemplateGraphicalModel)) {
pm = pm.getParent();
}
if (data instanceof IFreemarkerTemplateModel && pm instanceof FreemarkerTemplateGraphicalModel) {
TemplateBuilder builder = ((FreemarkerTemplateGraphicalModel) pm).getTemplateBuilder();
if (((IFreemarkerTemplateModel) data).isRequired() && !((IFreemarkerTemplateModel) data).isHidden(builder)) {
if (abstractSmooksGraphicalModel.getTargetConnections().isEmpty()) {
return true;
}
}
}
return false;
}
public static boolean isRequiredCollectionNode(AbstractSmooksGraphicalModel abstractSmooksGraphicalModel) {
Object data = abstractSmooksGraphicalModel.getData();
if (data instanceof IFreemarkerTemplateModel) {
if (((IFreemarkerTemplateModel) data).isManyOccurs()) {
if (abstractSmooksGraphicalModel.getTargetConnections().isEmpty()) {
return enforceCollectionSubMappingRules(abstractSmooksGraphicalModel);
}
}
}
return false;
}
public static boolean enforceCollectionSubMappingRules(AbstractSmooksGraphicalModel abstractSmooksGraphicalModel) {
Object data = abstractSmooksGraphicalModel.getData();
if (data instanceof IFreemarkerTemplateModel) {
Node modelNode = ((IFreemarkerTemplateModel) data).getModelNode();
if(modelNode instanceof Element) {
return ModelBuilder.getEnforceCollectionSubMappingRules((Element) modelNode);
}
}
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#
* getAutoLayout()
*/
@Override
public IAutoLayout getAutoLayout() {
if (autoLayout == null) {
autoLayout = new FreemarkerAutoLayout();
}
return autoLayout;
}
/*
* (non-Javadoc)
*
* @seeorg.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#
* createConnectionModelFactory()
*/
@Override
protected ConnectionModelFactory createConnectionModelFactory() {
return new FreemarkerTemplateConnectionModelFactory(this.getSmooksModelProvider(), this);
}
/*
* (non-Javadoc)
*
* @seeorg.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#
* createGraphicalModelFactory()
*/
@Override
protected GraphicalModelFactory createGraphicalModelFactory() {
return new FreemarkerTemplateGraphicalModelFactory(this.getSmooksModelProvider(), this);
}
/*
* (non-Javadoc)
*
* @see
* org.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#getID
* ()
*/
@Override
public String getID() {
return ID;
}
/* (non-Javadoc)
* @see org.jboss.tools.smooks.graphical.editors.SmooksGraphicalEditorPart#createInputDataGraphModel()
*/
@Override
protected List<AbstractSmooksGraphicalModel> createInputDataGraphModel() {
if(isConnectedDirectlyToInputTask()) {
return super.createInputDataGraphModel();
} else {
return Collections.EMPTY_LIST;
}
}
}