/*
* Copyright 2017 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.svg.gen.translator.impl;
import java.util.LinkedList;
import java.util.List;
import org.kie.workbench.common.stunner.svg.client.shape.view.SVGShapeView;
import org.kie.workbench.common.stunner.svg.gen.exception.TranslatorException;
import org.kie.workbench.common.stunner.svg.gen.model.PrimitiveDefinition;
import org.kie.workbench.common.stunner.svg.gen.model.ViewDefinition;
import org.kie.workbench.common.stunner.svg.gen.model.ViewRefDefinition;
import org.kie.workbench.common.stunner.svg.gen.model.impl.ViewDefinitionImpl;
import org.kie.workbench.common.stunner.svg.gen.translator.SVGDocumentTranslator;
import org.kie.workbench.common.stunner.svg.gen.translator.SVGElementTranslator;
import org.kie.workbench.common.stunner.svg.gen.translator.css.SVGAttributeParserUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class SVGDocumentTranslatorImpl implements SVGDocumentTranslator {
private static final String SVG_TAG = "svg";
public static final String X = "x";
public static final double X_DEFAULT = 0d;
public static final String Y = "y";
public static final double Y_DEFAULT = 0d;
public static final String WIDTH = "width";
public static final String HEIGHT = "height";
public static final String VIEW_BOX = "viewBox";
private final SVGElementTranslator<Element, Object>[] elementTranslators;
public SVGDocumentTranslatorImpl(final SVGElementTranslator<Element, Object>[] elementTranslators) {
this.elementTranslators = elementTranslators;
}
@Override
public Class<Document> getInputType() {
return Document.class;
}
@Override
@SuppressWarnings("unchecked")
public ViewDefinition<SVGShapeView> translate(final Document root) throws TranslatorException {
final SVGTranslatorContextImpl context = new SVGTranslatorContextImpl(root,
elementTranslators);
// Process the SVG node stuff.
String svgId = null;
final double[] svgCoord = new double[]{0d, 0d};
final double[] svgSize = new double[]{0d, 0d};
final ViewDefinition.ViewBoxDefinition[] viewBox = new ViewDefinition.ViewBoxDefinition[1];
final NodeList svgNodes = root.getElementsByTagName(SVG_TAG);
if (null != svgNodes && 1 == svgNodes.getLength()) {
final Element svgNode = (Element) svgNodes.item(0);
// SVG id.
svgId = svgNode.getAttribute(X);
// View box.
final String x = svgNode.getAttribute(X);
final String y = svgNode.getAttribute(Y);
final String width = svgNode.getAttribute(WIDTH);
final String height = svgNode.getAttribute(HEIGHT);
svgCoord[0] = SVGAttributeParserUtils.toPixelValue(x,
X_DEFAULT);
svgCoord[1] = SVGAttributeParserUtils.toPixelValue(y,
Y_DEFAULT);
svgSize[0] = SVGAttributeParserUtils.toPixelValue(width);
svgSize[1] = SVGAttributeParserUtils.toPixelValue(height);
final String vbox = svgNode.getAttribute(VIEW_BOX);
viewBox[0] = SVGViewBoxTranslator.translate(vbox);
} else {
throw new TranslatorException("No SVG root node found!");
}
// Parser innver SVG View elements.
PrimitiveDefinition<?> potentialMainShape = null;
PrimitiveDefinition<?> mainShape = null;
final List<PrimitiveDefinition<?>> result = new LinkedList<>();
for (final SVGElementTranslator<Element, Object> translator : elementTranslators) {
final String tagName = translator.getTagName();
final NodeList nodes = root.getElementsByTagName(tagName);
if (null != nodes && 0 < nodes.getLength()) {
for (int i = 0; i < nodes.getLength(); i++) {
final Element node = (Element) nodes.item(i);
final Object definition = translator.translate(node,
context);
if (null != definition) {
if (definition instanceof PrimitiveDefinition) {
final PrimitiveDefinition primitiveDefinition = (PrimitiveDefinition) definition;
if (primitiveDefinition.isMain()) {
mainShape = primitiveDefinition;
} else if (null == potentialMainShape) {
potentialMainShape = primitiveDefinition;
} else {
result.add(primitiveDefinition);
}
} else if (definition instanceof ViewRefDefinition) {
context.addSVGViewRef((ViewRefDefinition) definition);
}
}
}
}
}
if (null != mainShape && null != potentialMainShape) {
result.add(potentialMainShape);
}
final PrimitiveDefinition<?> main = null != mainShape ? mainShape : potentialMainShape;
if (null == main) {
throw new TranslatorException("No SVG main node found!!");
}
final ViewDefinition viewDefinition =
new ViewDefinitionImpl(svgId,
svgCoord[0],
svgCoord[1],
svgSize[0],
svgSize[1],
viewBox[0],
main,
result.toArray(new PrimitiveDefinition<?>[result.size()]));
viewDefinition.getSVGViewRefs().addAll(context.viewRefDefinitions);
return viewDefinition;
}
}