All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.primefaces.component.diagram.DiagramRenderer Maven / Gradle / Ivy

There is a newer version: 14.0.0-RC3
Show newest version
/*
 * Copyright 2009-2014 PrimeTek.
 *
 * 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.primefaces.component.diagram;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.primefaces.model.diagram.DiagramModel;
import org.primefaces.model.diagram.Element;
import org.primefaces.model.diagram.Connection;
import org.primefaces.model.diagram.connector.Connector;
import org.primefaces.model.diagram.endpoint.EndPoint;
import org.primefaces.model.diagram.overlay.Overlay;
import org.primefaces.renderkit.CoreRenderer;
import org.primefaces.util.SharedStringBuilder;
import org.primefaces.util.WidgetBuilder;

public class DiagramRenderer extends CoreRenderer {
    
    private static final String SB_DIAGRAM = CoreRenderer.class.getName() + "#diagram";

    @Override
    public void decode(FacesContext context, UIComponent component) {
        Diagram diagram = (Diagram) component;
        
        if(diagram.isConnectRequest(context)) {
            decodeNewConnection(context, diagram);
        } else if(diagram.isDisconnectRequest(context)) {
            decodeDisconnection(context, diagram);
        } else if(diagram.isConnectionChangeRequest(context)) {
            decodeConnectionChange(context, diagram);
        }
        
        decodeBehaviors(context, component);
    }
    
    private void decodeNewConnection(FacesContext context, Diagram diagram) {
        //no need to decode since state is synced in previous connection move request
        if(context.getExternalContext().getRequestParameterMap().containsKey(diagram.getClientId(context) + "_connectionChanged")) {
            return;
        }
        
        DiagramModel model = (DiagramModel) diagram.getValue();
        if(model != null) {
            Connection connection = decodeConnection(context, diagram, true);
            if(connection != null) {
                model.connect(connection);
            }
        }
    }
    
    private void decodeDisconnection(FacesContext context, Diagram diagram) {
        DiagramModel model = (DiagramModel) diagram.getValue();
        if(model != null) {
            Connection connection = decodeConnection(context, diagram, false);
            if(connection != null) {
                model.disconnect(connection);
            }
        }
    }
    
    private void decodeConnectionChange(FacesContext context, Diagram diagram) {
        DiagramModel model = (DiagramModel) diagram.getValue();
        if(model != null) {
            Map params = context.getExternalContext().getRequestParameterMap();
            String clientId = diagram.getClientId(context);
            
            Element originalSourceElement = model.findElement(params.get(clientId + "_originalSourceId"));
            Element newSourceElement = model.findElement(params.get(clientId + "_newSourceId"));
            Element originalTargetElement = model.findElement(params.get(clientId + "_originalTargetId"));
            Element newTargetElement = model.findElement(params.get(clientId + "_newTargetId"));
            EndPoint originalSourceEndPoint = model.findEndPoint(originalSourceElement, params.get(clientId + "_originalSourceEndPointId"));
            EndPoint newSourceEndPoint = model.findEndPoint(newSourceElement, params.get(clientId + "_newSourceEndPointId"));
            EndPoint originalTargetEndPoint = model.findEndPoint(originalTargetElement, params.get(clientId + "_originalTargetEndPointId"));
            EndPoint newTargetEndPoint = model.findEndPoint(newTargetElement, params.get(clientId + "_newTargetEndPointId"));
        
            model.disconnect(findConnection(model, originalSourceEndPoint, originalTargetEndPoint));
            model.connect(new Connection(newSourceEndPoint, newTargetEndPoint));
        }
    }
    
    private Connection decodeConnection(FacesContext context, Diagram diagram, boolean createNew) {
        DiagramModel model = (DiagramModel) diagram.getValue();
        Connection connection = null;
        
        if(model != null) {
            Map params = context.getExternalContext().getRequestParameterMap();
            String clientId = diagram.getClientId(context);

            Element sourceElement = model.findElement(params.get(clientId + "_sourceId"));
            Element targetElement = model.findElement(params.get(clientId + "_targetId"));
            EndPoint sourceEndPoint = model.findEndPoint(sourceElement, params.get(clientId + "_sourceEndPointId"));
            EndPoint targetEndPoint = model.findEndPoint(targetElement, params.get(clientId + "_targetEndPointId"));
            
            if(createNew)
                connection = new Connection(sourceEndPoint, targetEndPoint);
            else
                connection = findConnection(model, sourceEndPoint, targetEndPoint);
        }
        
        return connection;
    }
    
    private Connection findConnection(DiagramModel model, EndPoint source, EndPoint target) {
        Connection connection = null;
        
        if(model != null) {
            List connections = model.getConnections();
            if(connections != null) {
                int connectionsSize = connections.size();
                for(int i = 0; i < connectionsSize; i++) {
                    Connection conn = connections.get(i);

                    if(conn.getSource().equals(source) && conn.getTarget().equals(target)) {
                        connection = conn;
                        break;
                    }
                }
            }
        }
        
        return connection;
    }
    
    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        Diagram diagram = (Diagram) component;

        encodeMarkup(context, diagram);
		encodeScript(context, diagram);
    }
    
    protected void encodeScript(FacesContext context, Diagram diagram) throws IOException {
        String clientId = diagram.getClientId(context);
        StringBuilder sb = SharedStringBuilder.get(SB_DIAGRAM);
        WidgetBuilder wb = getWidgetBuilder(context);
        wb.init("Diagram", diagram.resolveWidgetVar(), clientId, "diagram");
        
        DiagramModel model = (DiagramModel) diagram.getValue();
        if(model != null) {
            encodeDefaults(wb, model);
            
            encodeEndPoints(wb, model, clientId);
            encodeConnections(wb, model);
        }
        
        encodeClientBehaviors(context, diagram);

        wb.finish();
    }
    
    protected void encodeDefaults(WidgetBuilder wb, DiagramModel  model) throws IOException {
        StringBuilder sb = SharedStringBuilder.get(SB_DIAGRAM);
        
        Connector defaultConnector = model.getDefaultConnector();
        if(defaultConnector != null) {
            String paintStyle = defaultConnector.getPaintStyle();
            String hoverPaintStyle = defaultConnector.getHoverPaintStyle();
            
            wb.append(",defaultConnector:").append(defaultConnector.toJS(sb));

            if(paintStyle != null) wb.append(",paintStyle:").append(paintStyle);
            if(hoverPaintStyle != null) wb.append(",hoverPaintStyle:").append(hoverPaintStyle);
                    
            sb.setLength(0);
        }
        
        encodeOverlays(wb, model.getDefaultConnectionOverlays(), "connectionOverlays");
        
        if(!model.isConnectionsDetachable()) {
            wb.append(",connectionsDetachable:false");
        }
        
        int maxConnections = model.getMaxConnections();
        if(maxConnections != 1) {
            wb.append(",maxConnections:").append(maxConnections);
        }
    }
    
    protected void encodeEndPoints(WidgetBuilder wb, DiagramModel model, String clientId) throws IOException {
        List elements = model.getElements();
        if(elements != null && !elements.isEmpty()) {
            int elementsSize = elements.size();

            wb.append(",endPoints:[");                
            for(int i = 0; i < elementsSize; i++) {
                Element element = elements.get(i);
                String elementClientId = clientId + "-" + element.getId();
                List endPoints = element.getEndPoints();

                if(endPoints != null && !endPoints.isEmpty()) {
                    int endPointsSize = endPoints.size();

                    for(int j = 0; j < endPointsSize; j++) {
                        EndPoint endPoint = endPoints.get(j);
                        encodeEndPoint(wb, endPoint, elementClientId);

                        if(j < (endPointsSize - 1)) {
                            wb.append(",");
                        }
                    }
                }

                if(i < (elementsSize - 1)) {
                    wb.append(",");
                }
            }
            wb.append("]");
        }
    }
            
    protected void encodeEndPoint(WidgetBuilder wb, EndPoint endPoint, String elementClientId) throws IOException {
        String type = endPoint.getType();
        StringBuilder sb = SharedStringBuilder.get(SB_DIAGRAM);
        String styleClass = endPoint.getStyleClass();
        String hoverStyleClass = endPoint.getHoverStyleClass();
        String style = endPoint.getStyle();
        String hoverStyle = endPoint.getHoverStyle();
        int maxConnections = endPoint.getMaxConnections();
        String scope = endPoint.getScope();

        wb.append("{uuid:'").append(endPoint.getId()).append("'")
            .append(",element:'").append(elementClientId).append("'")
            .append(",anchor:'").append(endPoint.getAnchor().toString()).append("'");

        if(maxConnections != 1) wb.append(",maxConnections:").append(maxConnections);
        if(style != null) wb.append(",paintStyle:").append(style);
        if(hoverStyle != null) wb.append(",hoverPaintStyle:").append(hoverStyle);
        if(endPoint.isSource()) wb.append(",isSource:true");
        if(endPoint.isTarget()) wb.append(",isTarget:true");
        if(styleClass != null) wb.append(",cssClass:'").append(styleClass).append("'");
        if(hoverStyleClass != null) wb.append(",hoverClass:'").append(hoverStyleClass).append("'");
        if(scope != null) wb.append(",scope:'").append(scope).append("'");

        if(type != null) {
            wb.append(",endpoint:").append(endPoint.toJS(sb));
        }
        
        encodeOverlays(wb, endPoint.getOverlays(), "overlays");

        wb.append("}");
    }
    
    protected void encodeConnections(WidgetBuilder wb, DiagramModel model) throws IOException {
        List connections = model.getConnections();
        if(connections != null && !connections.isEmpty()) {
            int connectionsSize = connections.size();

            wb.append(",connections:[");          
            for(int i = 0; i < connectionsSize; i++) {
                Connection connection = connections.get(i);
                StringBuilder sb = SharedStringBuilder.get(SB_DIAGRAM);
                Connector connector = connection.getConnector();
                List overlays = connection.getOverlays();

                wb.append("{uuids:['").append(connection.getSource().getId()).append("'")
                            .append(",'").append(connection.getTarget().getId()).append("']");
                
                if(connector != null && connector.getType() != null) {
                    wb.append(",connector:").append(connector.toJS(sb));
                    
                    String paintStyle = connector.getPaintStyle();
                    String hoverPaintStyle = connector.getHoverPaintStyle();
                    
                    if(paintStyle != null) wb.append(",paintStyle:").append(paintStyle);
                    if(hoverPaintStyle != null) wb.append(",hoverPaintStyle:").append(hoverPaintStyle);
                }
                
                if(!connection.isDetachable()) {
                    wb.append(",detachable:false");
                }
                
                encodeOverlays(wb, overlays, "overlays");

                wb.append("}");

                if(i < (connectionsSize - 1)) {
                    wb.append(",");
                }

            }
            wb.append("]");
        }
    }
    
    protected void encodeOverlays(WidgetBuilder wb, List overlays, String propertyName) throws IOException {
        StringBuilder sb = SharedStringBuilder.get(SB_DIAGRAM);
         
        if(overlays != null && !overlays.isEmpty()) {
            int overlaysSize = overlays.size();
                    
            wb.append(",").append(propertyName).append(":[");
            for(int j = 0; j < overlaysSize; j++) {
                Overlay overlay = overlays.get(j);
                sb.setLength(0);

                wb.append(overlay.toJS(sb));

                if(j < (overlaysSize - 1)) {
                    wb.append(",");
                }
            }
            wb.append("]");
        }
    }
        
    protected void encodeMarkup(FacesContext context, Diagram diagram) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        DiagramModel model = (DiagramModel) diagram.getValue();
        String clientId = diagram.getClientId(context);
        String style = diagram.getStyle();
        String styleClass = diagram.getStyleClass();
        styleClass = (styleClass == null) ? Diagram.CONTAINER_CLASS : Diagram.CONTAINER_CLASS + " " + styleClass;
        UIComponent elementFacet = diagram.getFacet("element");
        Map requestMap = context.getExternalContext().getRequestMap();
        String var = diagram.getVar();
        
        writer.startElement("div", diagram);
        writer.writeAttribute("id", diagram.getClientId(context), null);
        writer.writeAttribute("class", styleClass, null);
        if(style != null) {
            writer.writeAttribute("style", style, null);
        }
        
        if(model != null) {
            List elements = model.getElements();
            if(elements != null && !elements.isEmpty()) {
                for(int i = 0; i < elements.size(); i++) {
                    Element element = elements.get(i);
                    String elementClass = element.getStyleClass();
                    elementClass = (elementClass == null) ? Diagram.ELEMENT_CLASS : Diagram.ELEMENT_CLASS + " " + elementClass;
                    if(element.isDraggable()) {
                        elementClass = elementClass + " " + Diagram.DRAGGABLE_ELEMENT_CLASS;
                    }
                    Object data = element.getData();
                    String x = element.getX();
                    String y = element.getY();
                    String coords = "left:" + x + ";top:" + y;
                    
                    writer.startElement("div", null);
                    writer.writeAttribute("id", clientId + "-" + element.getId(), null);
                    writer.writeAttribute("class", elementClass, null);
                    writer.writeAttribute("style", coords, null);
                    
                    if(elementFacet != null && var != null) {
                        requestMap.put(var, data);
                        elementFacet.encodeAll(context);
                    } 
                    else if(data != null) {
                        writer.writeText(data, null);
                    }
                    writer.endElement("div");
                }
            }
            
            if(var != null) {
                requestMap.remove(var);
            }
        }
        
        writer.endElement("div");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy