001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Alexandre Russel
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.mail.action;
021
022import java.util.HashMap;
023import java.util.Map;
024
025import org.nuxeo.common.xmap.annotation.XNode;
026import org.nuxeo.common.xmap.annotation.XNodeList;
027import org.nuxeo.common.xmap.annotation.XObject;
028
029/**
030 * @author Alexandre Russel
031 * @author Laurent Doguin
032 */
033@XObject("pipe")
034public class MessageActionPipeDescriptor {
035
036    private static final String START_ACTION = "StartAction";
037
038    @XNode("@name")
039    private String name;
040
041    @XNode("@override")
042    private Boolean override;
043
044    private final Map<String, MessageActionDescriptor> actionDescriptorsRegistry = new HashMap<String, MessageActionDescriptor>();
045
046    private MessageActionPipe pipe = new MessageActionPipe();
047
048    @XNodeList(value = "action", type = MessageActionDescriptor[].class, componentType = MessageActionDescriptor.class)
049    MessageActionDescriptor[] actions;
050
051    public String getName() {
052        return name;
053    }
054
055    public boolean getOverride() {
056        if (override == null) {
057            return false;
058        }
059        return override;
060    }
061
062    public Map<String, MessageActionDescriptor> getActions() {
063        for (MessageActionDescriptor action : actions) {
064            actionDescriptorsRegistry.put(action.getId(), action);
065        }
066        return actionDescriptorsRegistry;
067    }
068
069    /**
070     * Merge this MessageActionPipeDescriptor with the given one.
071     */
072    public void merge(MessageActionPipeDescriptor descriptor) {
073        for (String actionName : descriptor.getActions().keySet()) {
074            actionDescriptorsRegistry.put(actionName, descriptor.getActions().get(actionName));
075        }
076        pipe = new MessageActionPipe();
077    }
078
079    /**
080     * @return initialized action pipe
081     */
082    public MessageActionPipe getPipe() {
083        if (pipe.isEmpty()) {
084            fillMissingActionDestination();
085            MessageActionDescriptor initialAction = getActions().get(START_ACTION);
086            addAction(initialAction);
087        }
088        return pipe;
089    }
090
091    private void addAction(MessageActionDescriptor msgActionDescriptor) {
092        pipe.add(msgActionDescriptor.getAction());
093        String next = msgActionDescriptor.getTo();
094        MessageActionDescriptor nextAction = actionDescriptorsRegistry.get(next);
095        if (nextAction == null) {
096            return;
097        } else {
098            addAction(nextAction);
099        }
100    }
101
102    /**
103     * Fill empty destination using registering order to preserve backward compatibility.
104     */
105    private void fillMissingActionDestination() {
106        for (int i = 0; i < actions.length - 1; i++) {
107            String destination = actions[i].getTo();
108            if (destination == null || "".equals(destination)) {
109                String newDestination = actions[i + 1].getId();
110                if (newDestination != null) {
111                    actions[i].setTo(newDestination);
112                }
113            }
114        }
115    }
116}