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.spec; 021 022 import java.util.Collections; 023 import java.util.HashMap; 024 import java.util.Iterator; 025 import java.util.LinkedList; 026 import java.util.List; 027 import java.util.Map; 028 import java.util.Map.Entry; 029 030 import org.dom4j.Document; 031 import org.dom4j.DocumentHelper; 032 import org.dom4j.Element; 033 import org.mactor.framework.MactorException; 034 import org.mactor.framework.ParseUtil; 035 036 public class MessageBrokersConfig { 037 private List<MessageBrokerConfig> brokers = new LinkedList<MessageBrokerConfig>(); 038 private Document doc; 039 public String asXML() { 040 return XmlUtil.getPrettyXML(doc.getRootElement()); 041 } 042 public List<MessageBrokerConfig> getMessageBrokers() { 043 return Collections.unmodifiableList(brokers); 044 } 045 public MessageBrokersConfig(Document doc) throws MactorException { 046 if (doc == null || doc.getRootElement() == null) 047 throw new MactorException("Invalid MessageBrokerConfig: null"); 048 this.doc = doc; 049 Element element = doc.getRootElement(); 050 if (!"message_broker_config".equals(element.getName())) 051 throw new MactorException("Invalid MessageBrokerConfig. Root node: '" + element.getName() + "'. Expected: 'message_broker_config'"); 052 Iterator it = element.elementIterator("message_broker"); 053 while (it.hasNext()) { 054 brokers.add(MessageBrokerConfig.loadConfig((Element) it.next())); 055 } 056 } 057 public static class MessageBrokerConfig { 058 private Map<String, ChannelConfig> channels = new HashMap<String, ChannelConfig>(); 059 private Map<String, String> values = new HashMap<String, String>(); 060 private String brokerClass; 061 private String name; 062 private String archivePath; 063 private boolean arhiveDeadLetterMessage; 064 private boolean archiveConsumedMessages; 065 private int messageReadLimit; 066 private int messageReadIntervalSeconds; 067 public boolean isArchiveConsumedMessages() { 068 return archiveConsumedMessages; 069 } 070 public String getArchivePath() { 071 return archivePath; 072 } 073 public boolean isArhiveDeadLetterMessage() { 074 return arhiveDeadLetterMessage; 075 } 076 public String getBrokerClass() { 077 return brokerClass; 078 } 079 public Map<String, ChannelConfig> getChannels() { 080 return channels; 081 } 082 public String getName() { 083 return name; 084 } 085 public Map<String, String> getValues() { 086 return values; 087 } 088 public String getValue(String name) { 089 return values.get(name); 090 } 091 public ChannelConfig getChannelConfig(String channelName) { 092 return channels.get(channelName); 093 } 094 public ChannelConfig getRequieredChannelConfig(String channelName) throws MactorException { 095 ChannelConfig cf = channels.get(channelName); 096 if (cf == null) 097 throw new MactorException("There is no channel config for channel '" + channelName + "'"); 098 return cf; 099 } 100 private static MessageBrokerConfig loadConfig(Element element) throws MactorException { 101 MessageBrokerConfig mbc = new MessageBrokerConfig(); 102 mbc.name = element.attributeValue("name"); 103 mbc.archivePath = element.attributeValue("archive_path"); 104 mbc.brokerClass = element.attributeValue("broker_class"); 105 mbc.messageReadIntervalSeconds = ParseUtil.tryParseIntVal(element.attributeValue("message_read_interval_seconds")); 106 if (mbc.messageReadIntervalSeconds == 0) 107 mbc.messageReadIntervalSeconds = 10; 108 mbc.messageReadLimit = ParseUtil.tryParseIntVal(element.attributeValue("message_read_limit")); 109 if (mbc.messageReadLimit == 0) 110 mbc.messageReadLimit = 20; 111 mbc.archiveConsumedMessages = Boolean.parseBoolean(element.attributeValue("archive_consumed_messages")); 112 mbc.arhiveDeadLetterMessage = Boolean.parseBoolean(element.attributeValue("archive_dead_letter_messages")); 113 Iterator it = element.elementIterator("channel"); 114 while (it.hasNext()) { 115 ChannelConfig c = ChannelConfig.loadConfig((Element) it.next()); 116 mbc.channels.put(c.getName(), c); 117 } 118 it = element.elementIterator("value"); 119 while (it.hasNext()) { 120 Element e = (Element) it.next(); 121 mbc.values.put(e.attributeValue("name"), e.getTextTrim()); 122 } 123 return mbc; 124 } 125 public static class ChannelConfig { 126 private Map<String, String> values = new HashMap<String, String>(); 127 private String name; 128 private boolean requiresResponse; 129 public String getValue(String valueName) { 130 return values.get(valueName); 131 } 132 public String getRequieredValue(String valueName) throws MactorException { 133 String value = getValue(valueName); 134 if (value == null) 135 throw new MactorException("The channel config named '" + name + "' does not specify the requiered value '" + valueName + "'"); 136 return value; 137 } 138 public String getValue(String valueName, String defValue) { 139 String v = values.get(valueName); 140 return v == null ? defValue : v; 141 } 142 public static ChannelConfig loadConfig(Element element) throws MactorException { 143 ChannelConfig c = new ChannelConfig(); 144 c.name = element.attributeValue("name"); 145 c.requiresResponse = Boolean.parseBoolean(element.attributeValue("requires_response")); 146 Iterator it = element.elementIterator("value"); 147 while (it.hasNext()) { 148 Element e = (Element) it.next(); 149 c.values.put(e.attributeValue("name"), e.getTextTrim()); 150 } 151 return c; 152 } 153 public String getName() { 154 return name; 155 } 156 public Map<String, String> getValues() { 157 return values; 158 } 159 private void writeNodes(Element e) { 160 e.addAttribute("name", getName()); 161 e.addAttribute("requires_response", requiresResponse + ""); 162 for (Entry<String, String> entry : values.entrySet()) { 163 Element val = e.addElement("value"); 164 val.addAttribute("name", entry.getKey()); 165 val.setText(entry.getValue().trim()); 166 } 167 } 168 public boolean isRequiresResponse() { 169 return requiresResponse; 170 } 171 } 172 public int getMessageReadIntervalSeconds() { 173 return messageReadIntervalSeconds; 174 } 175 public int getMessageReadLimit() { 176 return messageReadLimit; 177 } 178 private void writeNodes(Element e) { 179 e.addAttribute("archive_path", getArchivePath() + ""); 180 e.addAttribute("broker_class", getBrokerClass()); 181 e.addAttribute("message_read_interval_seconds", getMessageReadLimit() + ""); 182 e.addAttribute("archive_consumed_messages", isArchiveConsumedMessages() + ""); 183 e.addAttribute("archive_dead_letter_messages", isArhiveDeadLetterMessage() + ""); 184 for (Entry<String, ChannelConfig> entry : channels.entrySet()) { 185 Element channelElement = e.addElement("channel"); 186 entry.getValue().writeNodes(channelElement); 187 } 188 } 189 } 190 private void writeNodes(Element e) { 191 for (MessageBrokerConfig config : brokers) 192 config.writeNodes(e.addElement("message_brokers_config")); 193 } 194 public Document toNewDocument() { 195 Document newDoc = DocumentHelper.createDocument(); 196 writeNodes(newDoc.addElement("message_brokers_config")); 197 return newDoc; 198 } 199 }