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.brokers;
021    
022    import java.io.File;
023    import java.io.FileReader;
024    import java.io.FileWriter;
025    import java.io.IOException;
026    import java.io.InputStream;
027    import java.io.Reader;
028    import java.util.Map;
029    
030    import javax.xml.transform.Templates;
031    import javax.xml.transform.TransformerException;
032    import javax.xml.transform.TransformerFactory;
033    import javax.xml.transform.stream.StreamSource;
034    
035    import org.dom4j.Document;
036    import org.dom4j.DocumentException;
037    import org.dom4j.DocumentHelper;
038    import org.dom4j.io.DocumentResult;
039    import org.dom4j.io.DocumentSource;
040    import org.dom4j.io.SAXReader;
041    import org.mactor.framework.AppUtil;
042    import org.mactor.framework.MactorException;
043    
044    /**
045     * The message implementation
046     * 
047     * @author Lars Ivar Almli
048     */
049    public class Message {
050            private boolean consumed;
051            private Document doc;
052            private Document docNoNs;
053            private String content;
054            private Map<String, String> messageProperties;
055            private MessageContextInfo messageContextInfo;
056            private static String app_instance_id = AppUtil.getAppInstanceId();
057            private String id;
058            private static Object lock = new Object();
059            private static long counter = 0;
060            private static long getNextId() {
061                    synchronized (lock) {
062                            return counter++;
063                    }
064            }
065            public Message() {
066                    long seq = getNextId();
067                    this.id = app_instance_id + "_" + seq;
068                    this.messageContextInfo = new MessageContextInfo(seq);
069            }
070            public Map<String, String> getMessageProperties() {
071                    return messageProperties;
072            }
073            public void consume() {
074                    this.consumed = true;
075            }
076            public boolean isConsumed() {
077                    return consumed;
078            }
079            public String getContent() {
080                    return content;
081            }
082            public Document getContentDocument() throws MactorException {
083                    if (this.doc != null)
084                            return this.doc;
085                    try {
086                            this.doc = DocumentHelper.parseText(content);
087                            return this.doc;
088                    } catch (DocumentException de) {
089                            throw new MactorException("Can not construct a message from invalid XML. Error:" + de.getMessage() + ". Message: '" + content + "'", de);
090                    }
091            }
092            public static Message createMessage(String content) throws MactorException {
093                    if (content == null || content.length() == 0)
094                            throw new MactorException("Can not create a message wihtout content");
095                    return createMessage(content, null);
096            }
097            public static Message createMessage(String content, Map<String, String> messageProperties) throws MactorException {
098                    Message m = new Message();
099                    m.content = content;
100                    m.getContentDocument();// force parse..
101                    m.messageProperties = messageProperties;
102                    return m;
103            }
104            public static Message createMessage(Document doc) throws MactorException {
105                    return createMessage(doc, null);
106            }
107            public static Message createMessage(Document doc, Map<String, String> messageProperties) throws MactorException {
108                    Message m = new Message();
109                    m.doc = doc;
110                    m.content = doc.asXML();
111                    m.messageProperties = messageProperties;
112                    return m;
113            }
114            public static Message createMessage(InputStream inputStream) throws MactorException {
115                    return createMessage(inputStream, null);
116            }
117            public static Message createMessage(InputStream inputStream, Map<String, String> messageProperties) throws MactorException {
118                    try {
119                            Message m = new Message();
120                            m.doc = new SAXReader().read(inputStream);
121                            m.content = m.doc.asXML();
122                            m.messageProperties = messageProperties;
123                            return m;
124                    } catch (DocumentException de) {
125                            throw new MactorException(de);
126                    }
127            }
128            public static Message createMessage(Reader reader) throws MactorException {
129                    return createMessage(reader, null);
130            }
131            public static Message createMessage(Reader reader, Map<String, String> messageProperties) throws MactorException {
132                    try {
133                            Message m = new Message();
134                            m.doc = new SAXReader().read(reader);
135                            m.content = m.doc.asXML();
136                            m.messageProperties = messageProperties;
137                            return m;
138                    } catch (DocumentException de) {
139                            throw new MactorException(de);
140                    }
141            }
142            public static Message createMessage(File file) throws MactorException {
143                    return createMessage(file, null);
144            }
145            public static Message createMessage(File file, Map<String, String> messageProperties) throws MactorException {
146                    try {
147                            return createMessage(new FileReader(file), messageProperties);
148                    } catch (IOException ioe) {
149                            throw new MactorException("Failed to load the message from file '" + file.getAbsolutePath() + "'", ioe);
150                    }
151            }
152            public void writeToFile(File destFile) throws MactorException {
153                    try {
154                            FileWriter w = new FileWriter(destFile);
155                            doc.write(w);
156                            w.flush();
157                            w.close();
158                    } catch (IOException ioe) {
159                            throw new MactorException("Failed to write the  file '" + destFile.getAbsolutePath() + "'. Error:" + ioe.getMessage(), ioe);
160                    }
161            }
162            public Document getContentDocumentNoNs() throws MactorException {
163                    if (docNoNs != null)
164                            return docNoNs;
165                    if (doc == null)
166                            return null;
167                    try {
168                            TransformerFactory factory = TransformerFactory.newInstance();
169                            Templates t = factory.newTemplates(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("remove-ns.xsl")));
170                            DocumentSource source = new DocumentSource(doc);
171                            DocumentResult result = new DocumentResult();
172                            t.newTransformer().transform(source, result);
173                            this.docNoNs = result.getDocument();
174                            return docNoNs;
175                    } catch (TransformerException tfe) {
176                            throw new MactorException("Failed remove namespaces from document Error:" + tfe.getMessage(), tfe);
177                    }
178            }
179            public String getId() {
180                    return id;
181            }
182            public MessageContextInfo getMessageContextInfo() {
183                    return messageContextInfo;
184            }
185    }