001    /******************************************************************************
002     * Copyright (C) MActor Developers. All rights reserved.                        *
003     * ---------------------------------------------------------------------------*
004     * This file is part of MActor.                                               *
005     *                                                                            *
006     * MActor is free software; you can redistribute it and/or modify             *
007     * it under the terms of the GNU General Public License as published by       *
008     * the Free Software Foundation; either version 2 of the License, or          *
009     * (at your option) any later version.                                        *
010     *                                                                            *
011     * MActor is distributed in the hope that it will be useful,                  *
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
014     * GNU General Public License for more details.                               *
015     *                                                                            *
016     * You should have received a copy of the GNU General Public License          *
017     * along with MActor; if not, write to the Free Software                      *
018     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA *
019     ******************************************************************************/
020    package org.mactor.framework;
021    
022    import java.util.HashMap;
023    import java.util.Iterator;
024    import java.util.LinkedList;
025    import java.util.List;
026    import java.util.Map;
027    
028    import org.mactor.brokers.Message;
029    import org.mactor.framework.spec.GlobalConfig;
030    import org.mactor.framework.spec.SpecNode;
031    import org.mactor.framework.spec.TestSpec;
032    import org.mactor.framework.spec.GlobalConfig.Group;
033    
034    /**
035     * Maintains context information about the current executing test
036     * 
037     * @author Lars Ivar Almli
038     */
039    public class TestContextImpl implements TestContext {
040            private static final String START_TAG = "##{";
041            private static final String END_TAG = "}";
042            private Map<String, String> valueDic = new HashMap<String, String>();
043            private MessageHistoryStore sentMessageHistory = new MessageHistoryStore();
044            private MessageHistoryStore receivedMessageHistory = new MessageHistoryStore();
045            private GlobalConfig globalConfig;
046            private TestSpec testSpec;
047            public TestContextImpl(GlobalConfig globalConfig, TestSpec testSpec) {
048                    this.globalConfig = globalConfig;
049                    this.testSpec = testSpec;
050            }
051            public void setValues(Map<String, String> nameValueMap) {
052                    valueDic.putAll(nameValueMap);
053            }
054            public void setValue(String name, String value) {
055                    valueDic.put(name, value);
056            }
057            public Object getValue(String name) {
058                    return valueDic.get(name);
059            }
060            public Map<String, String> getValues() {
061                    return valueDic; // Collections.unmodifiableMap(
062            }
063            public void addReceivedMessage(String nodeName, Message message) {
064                    receivedMessageHistory.addMessage(nodeName, message);
065            }
066            public void addOutgoingMessage(String nodeName, Message message) {
067                    sentMessageHistory.addMessage(nodeName, message);
068            }
069            public Message getLastIncomingMessage() {
070                    return receivedMessageHistory.getLastMessage();
071            }
072            public Message getLastOutgoingMessage() {
073                    return sentMessageHistory.getLastMessage();
074            }
075            public List<Message> getIncomingMessageHistory(String nodeName) {
076                    return receivedMessageHistory.getMessageHistory(nodeName);
077            }
078            public List<Message> getOutgoingMessageHistory(String nodeName) {
079                    return sentMessageHistory.getMessageHistory(nodeName);
080            }
081            public List<Message> getIncomingMessageHistoryForCurrentNode() {
082                    return receivedMessageHistory.getLastModifiedMessageHistory();
083            }
084            public List<Message> getOutgoingMessageHistoryForCurrentNode() {
085                    return sentMessageHistory.getLastModifiedMessageHistory();
086            }
087            public List<String> substitute(List<String> candidates) {
088                    List<String> results = new LinkedList<String>();
089                    for (Iterator iter = candidates.iterator(); iter.hasNext();) {
090                            results.add(substitute((String) iter.next()));
091                    }
092                    return results;
093            }
094            public SpecNode getSpecNode(String nodeName) {
095                    return testSpec.findSpecNode(nodeName);
096            }
097            public String substitute(String candidate) {
098                    if (candidate == null)
099                            return null;
100                    StringBuffer sb = new StringBuffer();
101                    sub(sb, candidate);
102                    String v = sb.toString().trim();
103                    if (v.length() == 0)
104                            return null;
105                    return v;
106            }
107            private void sub(StringBuffer sb, String candidate) {
108                    if (candidate == null)
109                            return;
110                    int start = candidate.indexOf(START_TAG);
111                    if (start >= 0) {
112                            int end = candidate.indexOf(END_TAG, start + 3);
113                            if (end > 0) {
114                                    String tag = candidate.substring(start + 3, end);
115                                    if (valueDic.containsKey(tag)) {
116                                            sb.append(candidate.substring(0, start)).append(valueDic.get(tag));
117                                            if (end + 1 >= candidate.length())
118                                                    return;
119                                            else
120                                                    sub(sb, candidate.substring(end + 1, candidate.length()));
121                                    } else {
122                                            sb.append(candidate.substring(0, end + 1));
123                                            if (end + 1 >= candidate.length())
124                                                    return;
125                                            else
126                                                    sub(sb, candidate.substring(end + 1, candidate.length()));
127                                    }
128                                    return;
129                            }
130                    }
131                    sb.append(candidate);
132            }
133            // Config related methods:
134            public GlobalConfig getGlobalConfig() {
135                    return globalConfig;
136            }
137            public String getGlobalConfigValue(String valueName) {
138                    return globalConfig.getValue(valueName);
139            }
140            public Group getGlobalConfigGroup(String groupName) {
141                    return globalConfig.getGroup(groupName);
142            }
143            public Group getRequieredGlobalConfigGroup(String groupName) throws ConfigException {
144                    return globalConfig.getRequieredGroup(groupName);
145            }
146            private static class MessageHistoryStore {
147                    private MessageHistory lastModifedMessageHistory;
148                    private Map<String, MessageHistory> messageHistoryMap = new HashMap<String, MessageHistory>();
149                    public synchronized void addMessage(String node, Message message) {
150                            MessageHistory mh = messageHistoryMap.get(node);
151                            if (mh == null) {
152                                    mh = new MessageHistory();
153                                    messageHistoryMap.put(node, mh);
154                            }
155                            mh.addMessage(message);
156                            lastModifedMessageHistory = mh;
157                    }
158                    public synchronized List<Message> getLastModifiedMessageHistory() {
159                            if (lastModifedMessageHistory == null)
160                                    return null;
161                            return lastModifedMessageHistory.getMessages();
162                    }
163                    public synchronized Message getLastMessage() {
164                            if (lastModifedMessageHistory == null)
165                                    return null;
166                            return lastModifedMessageHistory.getLastMessage();
167                    }
168                    public synchronized List<Message> getMessageHistory(String nodeName) {
169                            MessageHistory mh = messageHistoryMap.get(nodeName);
170                            if (mh == null)
171                                    return null;
172                            return mh.getMessages();
173                    }
174            }
175            public LinkedList<Message> getAllMessages() {
176                    LinkedList<Message> all = new LinkedList<Message>();
177                    for (MessageHistory mh : sentMessageHistory.messageHistoryMap.values()) {
178                            all.addAll(mh.getMessages());
179                    }
180                    for (MessageHistory mh : receivedMessageHistory.messageHistoryMap.values()) {
181                            all.addAll(mh.getMessages());
182                    }
183                    return all;
184            }
185            private static class MessageHistory {
186                    private LinkedList<Message> history = new LinkedList<Message>();
187                    public void addMessage(Message message) {
188                            history.add(message);
189                    }
190                    public LinkedList<Message> getMessages() {
191                            return history;
192                    }
193                    public Message getLastMessage() {
194                            if (history.size() == 0)
195                                    return null;
196                            return history.getLast();
197                    }
198            }
199            public TestSpec getTestSpec() {
200                    return testSpec;
201            }
202    }