/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.workbench.common.stunner.shapes.client.factory;
import java.util.Map;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.kie.workbench.common.stunner.core.api.DefinitionManager;
import org.kie.workbench.common.stunner.core.api.FactoryManager;
import org.kie.workbench.common.stunner.core.client.canvas.AbstractCanvasHandler;
import org.kie.workbench.common.stunner.core.client.shape.HasChildren;
import org.kie.workbench.common.stunner.core.client.shape.Shape;
import org.kie.workbench.common.stunner.core.client.shape.factory.AbstractShapeDefFactory;
import org.kie.workbench.common.stunner.core.client.shape.view.ShapeView;
import org.kie.workbench.common.stunner.core.client.shape.view.glyph.Glyph;
import org.kie.workbench.common.stunner.core.client.shape.view.glyph.GlyphBuilderFactory;
import org.kie.workbench.common.stunner.core.definition.shape.GlyphDef;
import org.kie.workbench.common.stunner.core.definition.shape.ShapeDef;
import org.kie.workbench.common.stunner.shapes.client.CircleShape;
import org.kie.workbench.common.stunner.shapes.client.ConnectorShape;
import org.kie.workbench.common.stunner.shapes.client.PictureShape;
import org.kie.workbench.common.stunner.shapes.client.PolygonShape;
import org.kie.workbench.common.stunner.shapes.client.RectangleShape;
import org.kie.workbench.common.stunner.shapes.client.RingShape;
import org.kie.workbench.common.stunner.shapes.client.view.CircleView;
import org.kie.workbench.common.stunner.shapes.client.view.ConnectorView;
import org.kie.workbench.common.stunner.shapes.client.view.PictureShapeView;
import org.kie.workbench.common.stunner.shapes.client.view.PolygonView;
import org.kie.workbench.common.stunner.shapes.client.view.RectangleView;
import org.kie.workbench.common.stunner.shapes.client.view.RingView;
import org.kie.workbench.common.stunner.shapes.client.view.ShapeViewFactory;
import org.kie.workbench.common.stunner.shapes.def.CircleShapeDef;
import org.kie.workbench.common.stunner.shapes.def.ConnectorShapeDef;
import org.kie.workbench.common.stunner.shapes.def.HasChildShapeDefs;
import org.kie.workbench.common.stunner.shapes.def.PolygonShapeDef;
import org.kie.workbench.common.stunner.shapes.def.RectangleShapeDef;
import org.kie.workbench.common.stunner.shapes.def.RingShapeDef;
import org.kie.workbench.common.stunner.shapes.def.picture.PictureShapeDef;
import org.kie.workbench.common.stunner.shapes.factory.BasicShapesFactory;
@ApplicationScoped
public class BasicShapesFactoryImpl
extends AbstractShapeDefFactory<Object, ShapeView, Shape<ShapeView>, ShapeDef<Object>>
implements BasicShapesFactory<Object, AbstractCanvasHandler> {
private final ShapeViewFactory shapeViewFactory;
private final GlyphBuilderFactory glyphBuilderFactory;
protected BasicShapesFactoryImpl() {
this(null,
null,
null,
null);
}
@Inject
public BasicShapesFactoryImpl(final FactoryManager factoryManager,
final ShapeViewFactory shapeViewFactory,
final DefinitionManager definitionManager,
final GlyphBuilderFactory glyphBuilderFactory) {
super(definitionManager,
factoryManager);
this.shapeViewFactory = shapeViewFactory;
this.glyphBuilderFactory = glyphBuilderFactory;
}
@Override
@SuppressWarnings("unchecked")
public Shape<ShapeView> build(final Object definition,
final AbstractCanvasHandler context) {
final String id = definitionManager.adapters().forDefinition().getId(definition);
final ShapeDef<Object> proxy = getShapeDef(id);
return build(definition,
proxy,
context);
}
@SuppressWarnings("unchecked")
protected Shape<ShapeView> build(final Object definition,
final ShapeDef<Object> proxy,
final AbstractCanvasHandler context) {
boolean found = false;
Shape<? extends ShapeView> shape = null;
if (isCircle(proxy)) {
final CircleShapeDef<Object> circleProxy = (CircleShapeDef<Object>) proxy;
final double radius = circleProxy.getRadius(definition);
final CircleView view = shapeViewFactory.circle(radius);
shape = new CircleShape(circleProxy,
view);
found = true;
}
if (isRing(proxy)) {
final RingShapeDef<Object> ringProxy = (RingShapeDef<Object>) proxy;
final double oRadius = ringProxy.getOuterRadius(definition);
final RingView view = shapeViewFactory.ring(oRadius);
shape = new RingShape(ringProxy,
view);
found = true;
}
if (isRectangle(proxy)) {
final RectangleShapeDef<Object> rectangleProxy = (RectangleShapeDef<Object>) proxy;
final double width = rectangleProxy.getWidth(definition);
final double height = rectangleProxy.getHeight(definition);
final double cr = rectangleProxy.getCornerRadius(definition);
final RectangleView view = shapeViewFactory.rectangle(width,
height,
cr);
shape = new RectangleShape(rectangleProxy,
view);
found = true;
}
if (isPolygon(proxy)) {
final PolygonShapeDef<Object> polygonProxy = (PolygonShapeDef<Object>) proxy;
final double radius = polygonProxy.getRadius(definition);
final String fillColor = polygonProxy.getBackgroundColor(definition);
final PolygonView view = shapeViewFactory.polygon(radius,
fillColor);
shape = new PolygonShape(polygonProxy,
view);
found = true;
}
if (isConnector(proxy)) {
final ConnectorShapeDef<Object> polygonProxy = (ConnectorShapeDef<Object>) proxy;
final ConnectorView view = shapeViewFactory.connector(0,
0,
100,
100);
shape = new ConnectorShape(polygonProxy,
view);
found = true;
}
if (isPicture(proxy)) {
final PictureShapeDef pictureProxy = (PictureShapeDef) proxy;
final Object pictureSource = pictureProxy.getPictureSource(definition);
if (null != pictureSource) {
final double width = pictureProxy.getWidth(definition);
final double height = pictureProxy.getHeight(definition);
final PictureShapeView view = shapeViewFactory.picture(pictureSource,
width,
height);
// shape = new PictureShape(pictureProxy, view);
shape = new PictureShape(view);
}
found = true;
}
// Add children, if any.
if (null != shape
&& proxy instanceof HasChildShapeDefs) {
final HasChildShapeDefs<Object> hasChildren = (HasChildShapeDefs<Object>) proxy;
final Map<ShapeDef<Object>, HasChildren.Layout> childShapeDefs = hasChildren.getChildShapeDefs();
if (null != childShapeDefs && !childShapeDefs.isEmpty()) {
for (final Map.Entry<ShapeDef<Object>, HasChildren.Layout> entry : childShapeDefs.entrySet()) {
final ShapeDef<Object> child = entry.getKey();
final HasChildren.Layout layout = entry.getValue();
final Shape<ShapeView> childShape = this.build(definition,
child,
context);
if (null != childShape) {
((HasChildren) shape).addChild(childShape,
layout);
}
}
}
}
if (!found) {
final String id = definitionManager.adapters().forDefinition().getId(definition);
throw new RuntimeException("This factory supports [" + id + "] but cannot built a shape for it.");
}
return (Shape<ShapeView>) shape;
}
private boolean isCircle(final ShapeDef<Object> proxy) {
return proxy instanceof CircleShapeDef;
}
private boolean isRing(final ShapeDef<Object> proxy) {
return proxy instanceof RingShapeDef;
}
private boolean isRectangle(final ShapeDef<Object> proxy) {
return proxy instanceof RectangleShapeDef;
}
private boolean isPolygon(final ShapeDef<Object> proxy) {
return proxy instanceof PolygonShapeDef;
}
private boolean isConnector(final ShapeDef<Object> proxy) {
return proxy instanceof ConnectorShapeDef;
}
private boolean isPicture(final ShapeDef<Object> proxy) {
return proxy instanceof PictureShapeDef;
}
@Override
@SuppressWarnings("unchecked")
protected Glyph glyph(final Class<?> clazz,
final double width,
final double height) {
final ShapeDef<Object> shapeDef = getShapeDef(clazz);
final GlyphDef<Object> glyphDef = shapeDef.getGlyphDef();
return glyphBuilderFactory
.getBuilder(glyphDef)
.definitionType(clazz)
.glyphDef(glyphDef)
.factory(this)
.height(height)
.width(width)
.build();
}
}