/*******************************************************************************
* Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. 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
*
*******************************************************************************/
package com.cisco.yangide.ext.model.editor.diagram;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IAddFeature;
import org.eclipse.graphiti.features.ICreateFeature;
import org.eclipse.graphiti.features.IDirectEditingFeature;
import org.eclipse.graphiti.features.ILayoutFeature;
import org.eclipse.graphiti.features.IRemoveFeature;
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IAddConnectionContext;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.ICreateContext;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.context.IDirectEditingContext;
import org.eclipse.graphiti.features.context.ILayoutContext;
import org.eclipse.graphiti.features.context.IRemoveContext;
import org.eclipse.graphiti.features.context.IUpdateContext;
import org.eclipse.graphiti.features.custom.ICustomFeature;
import org.eclipse.graphiti.mm.algorithms.Text;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.pattern.CreateFeatureForPattern;
import org.eclipse.graphiti.pattern.DefaultFeatureProviderWithPatterns;
import org.eclipse.graphiti.pattern.IPattern;
import org.eclipse.swt.graphics.Point;
import com.cisco.yangide.core.YangCorePlugin;
import com.cisco.yangide.ext.model.ContainingNode;
import com.cisco.yangide.ext.model.editor.Activator;
import com.cisco.yangide.ext.model.editor.editors.ISourceModelManager;
import com.cisco.yangide.ext.model.editor.editors.YangDiagramBehavior;
import com.cisco.yangide.ext.model.editor.features.AddReferenceConnectionFeature;
import com.cisco.yangide.ext.model.editor.features.DiagramLayoutFeature;
import com.cisco.yangide.ext.model.editor.features.ExtractGroupingCustomFeature;
import com.cisco.yangide.ext.model.editor.features.RemoveConnectionFeature;
import com.cisco.yangide.ext.model.editor.features.TextDirectEditingFeature;
import com.cisco.yangide.ext.model.editor.features.UpdateTextFeature;
import com.cisco.yangide.ext.model.editor.patterns.objects.AnyxmlPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.AugmentPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.ChoiceCasePattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.ChoicePattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.ContainerPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.DeviationPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.ExtensionPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.FeaturePattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.GroupingPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.IdentityPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.LeafListPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.LeafPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.ListKeyPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.ListPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.NotificationPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.RpcIOPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.RpcPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.TypedefPattern;
import com.cisco.yangide.ext.model.editor.patterns.objects.UsesPattern;
import com.cisco.yangide.ext.model.editor.util.YangModelUIUtil;
public class EditorFeatureProvider extends DefaultFeatureProviderWithPatterns {
private static Map<String, String> TEMPLATES = new HashMap<>();
private ISourceModelManager sourceModelManager;
private int diagramWidth;
private int diagramHeight;
public EditorFeatureProvider(IDiagramTypeProvider dtp) {
super(dtp);
// objects
addPattern(new GroupingPattern());
addPattern(new LeafPattern());
addPattern(new ContainerPattern());
addPattern(new AnyxmlPattern());
addPattern(new RpcPattern());
addPattern(new RpcIOPattern(true));
addPattern(new RpcIOPattern(false));
addPattern(new UsesPattern());
addPattern(new NotificationPattern());
addPattern(new AugmentPattern());
addPattern(new DeviationPattern());
addPattern(new ExtensionPattern());
addPattern(new FeaturePattern());
addPattern(new IdentityPattern());
addPattern(new LeafListPattern());
addPattern(new ListPattern());
addPattern(new ChoicePattern());
addPattern(new ChoiceCasePattern());
addPattern(new TypedefPattern());
addPattern(new ListKeyPattern());
}
@Override
public IAddFeature getAddFeature(IAddContext context) {
if (context instanceof IAddConnectionContext) {
return new AddReferenceConnectionFeature(this);
}
return super.getAddFeature(context);
}
@Override
public IDirectEditingFeature getDirectEditingFeature(IDirectEditingContext context) {
if (context.getPictogramElement() instanceof Shape
&& ((Shape) context.getPictogramElement()).getGraphicsAlgorithm() instanceof Text) {
return new TextDirectEditingFeature(this);
}
return super.getDirectEditingFeature(context);
}
@Override
public IUpdateFeature getUpdateFeature(IUpdateContext context) {
if (context.getPictogramElement() instanceof Shape
&& ((Shape) context.getPictogramElement()).getGraphicsAlgorithm() instanceof Text) {
return new UpdateTextFeature(this);
}
return super.getUpdateFeature(context);
}
@Override
public ILayoutFeature getLayoutFeature(ILayoutContext context) {
if (context.getPictogramElement() instanceof Diagram) {
return new DiagramLayoutFeature(this);
}
return super.getLayoutFeature(context);
}
@Override
public ICustomFeature[] getCustomFeatures(ICustomContext context) {
return new ICustomFeature[] { new ExtractGroupingCustomFeature(this, sourceModelManager) };
}
@Override
public ICreateFeature[] getCreateFeatures() {
ICreateFeature[] ret = new ICreateFeature[0];
List<ICreateFeature> retList = new ArrayList<ICreateFeature>();
for (final IPattern pattern : getPatterns()) {
if (pattern.isPaletteApplicable()) {
retList.add(new CreateFeatureForPattern(this, pattern) {
@Override
public boolean canCreate(ICreateContext context) {
return pattern.canCreate(context);
}
@Override
public Object[] create(ICreateContext context) {
YangDiagramBehavior behavior = (YangDiagramBehavior) EditorFeatureProvider.this
.getDiagramTypeProvider().getDiagramBehavior();
behavior.setCreatePosition(new Point(context.getX(), context.getY()));
String name = this.getPattern().getCreateName();
if (!TEMPLATES.containsKey(name)) {
TEMPLATES.put(name, getTemplateContent(name));
}
EObject parent = (EObject) getBusinessObjectForPictogramElement(context.getTargetContainer());
int position = YangModelUIUtil.getPositionInParent(context.getTargetContainer(), context.getY(),
EditorFeatureProvider.this);
if (parent instanceof ContainingNode) {
ContainingNode node = (ContainingNode) parent;
String template = TEMPLATES.get(name);
template = template.replaceAll("@name@",
name.replaceAll("\\W", "-") + node.getChildren().size());
sourceModelManager.createSourceElement(node, position, template);
}
return new Object[0];
}
});
}
}
ICreateFeature[] a = getCreateFeaturesAdditional();
for (ICreateFeature element : a) {
retList.add(element);
}
return retList.toArray(ret);
}
@Override
public IRemoveFeature getRemoveFeature(IRemoveContext context) {
if (context.getPictogramElement() instanceof Connection) {
return new RemoveConnectionFeature(this);
}
return super.getRemoveFeature(context);
}
/**
* @param sourceModelManager the sourceModelManager to set
*/
public void setSourceModelManager(ISourceModelManager sourceModelManager) {
this.sourceModelManager = sourceModelManager;
}
/**
* @return InputStream of template with replaced placeholders.
* @throws IOException read errors
*/
private String getTemplateContent(String name) {
StringBuilder sb = new StringBuilder();
char[] buff = new char[1024];
int len = 0;
Path templatePath = new Path("templates/nodes/" + name + ".txt");
try (InputStreamReader in = new InputStreamReader(
FileLocator.openStream(Activator.getDefault().getBundle(), templatePath, false), "UTF-8")) {
while ((len = in.read(buff)) > 0) {
sb.append(buff, 0, len);
}
} catch (IOException e) {
YangCorePlugin.log(e);
}
return sb.toString();
}
public void updateDiagramSize(int x, int y) {
this.diagramWidth = x;
this.diagramHeight = y;
}
public int getDiagramHeight() {
return diagramHeight;
}
public int getDiagramWidth() {
return diagramWidth;
}
}