001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.jbi.framework;
018    
019    import java.io.PrintWriter;
020    import java.io.StringWriter;
021    import java.util.Iterator;
022    import java.util.List;
023    
024    import javax.jbi.management.DeploymentException;
025    import javax.xml.parsers.DocumentBuilder;
026    import javax.xml.parsers.DocumentBuilderFactory;
027    
028    import org.w3c.dom.Document;
029    import org.w3c.dom.Element;
030    import org.w3c.dom.Node;
031    
032    import org.apache.commons.logging.Log;
033    import org.apache.commons.logging.LogFactory;
034    import org.apache.servicemix.jbi.util.DOMUtil;
035    
036    /**
037     * ManagementMessageHelper is a class that ease the building of management messages. 
038     */
039    public final class ManagementSupport {
040        
041        private static final Log LOG = LogFactory.getLog(ManagementSupport.class);
042        
043        private ManagementSupport() {
044        }
045    
046        public static class Message {
047            private boolean isCauseFramework;
048            private String task;
049            private String result;
050            private Exception exception;
051            private String type;
052            private String message;
053            private String component;
054            private String locale;
055            
056            public Exception getException() {
057                return exception;
058            }
059            public void setException(Exception exception) {
060                this.exception = exception;
061            }
062            public boolean isCauseFramework() {
063                return isCauseFramework;
064            }
065            public void setCauseFramework(boolean value) {
066                this.isCauseFramework = value;
067            }
068            public String getMessage() {
069                return message;
070            }
071            public void setMessage(String message) {
072                this.message = message;
073            }
074            public String getResult() {
075                return result;
076            }
077            public void setResult(String result) {
078                this.result = result;
079            }
080            public String getTask() {
081                return task;
082            }
083            public void setTask(String task) {
084                this.task = task;
085            }
086            public String getType() {
087                return type;
088            }
089            public void setType(String type) {
090                this.type = type;
091            }
092            public String getComponent() {
093                return component;
094            }
095            public void setComponent(String component) {
096                this.component = component;
097            }
098            public String getLocale() {
099                return locale;
100            }
101            public void setLocale(String locale) {
102                this.locale = locale;
103            }
104        }
105        
106        public static Exception failure(String task, String info) throws Exception {
107            return failure(task, info, null, null);
108        }
109        
110        public static Exception failure(String task, List componentResults) throws Exception {
111            return failure(task, null, null, componentResults);
112        }
113        
114        public static Exception failure(String task, String info, Exception e) throws Exception {
115            return failure(task, info, e, null);
116        }
117        
118        public static Exception failure(String task, String info, Exception e, List componentResults) throws Exception {
119            ManagementSupport.Message msg = new ManagementSupport.Message();
120            msg.setTask(task);
121            msg.setResult("FAILED");
122            msg.setType("ERROR");
123            msg.setException(e);
124            msg.setMessage(info);
125            return new Exception(ManagementSupport.createFrameworkMessage(msg, componentResults));
126        }
127    
128        public static String createSuccessMessage(String task) {
129            return createSuccessMessage(task, null, null);
130        }
131        
132        public static String createSuccessMessage(String task, List componentResults) {
133            return createSuccessMessage(task, null, componentResults);
134        }
135        
136        public static String createSuccessMessage(String task, String info) {
137            return createSuccessMessage(task, info, null);
138        }
139    
140        public static String createSuccessMessage(String task, String info, List componentResults) {
141            ManagementSupport.Message msg = new ManagementSupport.Message();
142            msg.setTask(task);
143            msg.setResult("SUCCESS");
144            msg.setMessage(info);
145            return ManagementSupport.createFrameworkMessage(msg, componentResults);
146        }
147        
148        public static String createWarningMessage(String task, String info, List componentResults) {
149            ManagementSupport.Message msg = new ManagementSupport.Message();
150            msg.setTask(task);
151            msg.setResult("SUCCESS");
152            msg.setType("WARNING");
153            msg.setMessage(info);
154            return ManagementSupport.createFrameworkMessage(msg, componentResults);
155        }
156    
157        public static String createFrameworkMessage(Message fmkMsg, List componentResults) {
158            try {
159                Document doc = createDocument();
160                Element jbiTask = createChild(doc, "jbi-task");
161                jbiTask.setAttribute("xmlns", "http://java.sun.com/xml/ns/jbi/management-message");
162                jbiTask.setAttribute("version", "1.0");
163                Element jbiTaskResult = createChild(jbiTask, "jbi-task-result");
164                Element frmkTaskResult = createChild(jbiTaskResult, "frmwk-task-result");
165                Element frmkTaskResultDetails = createChild(frmkTaskResult, "frmwk-task-result-details");
166                appendTaskResultDetails(frmkTaskResultDetails, fmkMsg);
167                if (fmkMsg.getLocale() != null) {
168                    createChild(frmkTaskResult, "locale", fmkMsg.getLocale());
169                }
170                if (componentResults != null) {
171                    for (Iterator iter = componentResults.iterator(); iter.hasNext();) {
172                        Element element = (Element) iter.next();
173                        jbiTaskResult.appendChild(doc.importNode(element, true));
174                    }
175                }
176                return DOMUtil.asIndentedXML(doc);
177            } catch (Exception e) {
178                LOG.error("Error", e);
179                return null;
180            }
181        }
182        
183        private static Document createDocument() {
184            try {
185                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
186                factory.setNamespaceAware(true);
187                DocumentBuilder builder = factory.newDocumentBuilder();
188                return builder.newDocument();
189            } catch (Exception e) {
190                throw new RuntimeException("Could not create DOM document", e);
191            }
192        }
193        
194        private static Element createChild(Node parent, String name) {
195            return createChild(parent, name, null);
196        }
197        
198        private static Element createChild(Node parent, String name, String text) {
199            Document doc = parent instanceof Document ? (Document) parent : parent.getOwnerDocument();
200            Element child = doc.createElementNS("http://java.sun.com/xml/ns/jbi/management-message", name);
201            if (text != null) {
202                child.appendChild(doc.createTextNode(text));
203            }
204            parent.appendChild(child);
205            return child;
206        }
207        
208        private static void appendTaskResultDetails(Element root, Message fmkMsg) {
209            Element taskResultDetails = createChild(root, "task-result-details");
210            createChild(taskResultDetails, "task-id", fmkMsg.getTask());
211            createChild(taskResultDetails, "task-result", fmkMsg.getResult());
212            if (fmkMsg.getType() != null) {
213                createChild(taskResultDetails, "message-type", fmkMsg.getType());
214            }
215            // task-status-message
216            if (fmkMsg.getMessage() != null) {
217                Element taskStatusMessage = createChild(taskResultDetails, "task-status-msg");
218                Element msgLocInfo = createChild(taskStatusMessage, "msg-loc-info");
219                createChild(msgLocInfo, "loc-token");
220                createChild(msgLocInfo, "loc-message", fmkMsg.getMessage());
221            }
222            // exception-info
223            if (fmkMsg.getException() != null) {
224                Element exceptionInfo = createChild(taskResultDetails, "exception-info");
225                createChild(exceptionInfo, "nesting-level", "1");
226                createChild(exceptionInfo, "loc-token");
227                createChild(exceptionInfo, "loc-message", fmkMsg.getException().getMessage());
228                Element stackTrace = createChild(exceptionInfo, "stack-trace");
229                StringWriter sw2 = new StringWriter();
230                PrintWriter pw = new PrintWriter(sw2);
231                fmkMsg.getException().printStackTrace(pw);
232                pw.close();
233                stackTrace.appendChild(root.getOwnerDocument().createCDATASection(sw2.toString()));
234            }
235        }
236        
237        public static DeploymentException componentFailure(String task, String component, String info) {
238            try {
239                Element e = createComponentFailure(task, component, info, null);
240                return new DeploymentException(DOMUtil.asXML(e));
241            } catch (Exception e) {
242                if (LOG.isDebugEnabled()) {
243                    LOG.debug("Error creating management message", e);
244                }
245                return new DeploymentException(info);
246            }
247        }
248        
249        public static Element createComponentMessage(Message msg) {
250            Document doc = createDocument();
251            Element componentTaskResult = createChild(doc, "component-task-result");
252            createChild(componentTaskResult, "component-name", msg.getComponent());
253            Element componentTaskResultDetails = createChild(componentTaskResult, "component-task-result-details");
254            appendTaskResultDetails(componentTaskResultDetails, msg);
255            return componentTaskResult;
256        }
257        
258        public static Element createComponentSuccess(String task, String component) {
259            ManagementSupport.Message msg = new ManagementSupport.Message();
260            msg.setTask(task);
261            msg.setResult("SUCCESS");
262            msg.setComponent(component);
263            return createComponentMessage(msg);
264        }
265        
266        public static Element createComponentFailure(String task, String component, String info, Exception e) {
267            ManagementSupport.Message msg = new ManagementSupport.Message();
268            msg.setTask(task);
269            msg.setResult("FAILED");
270            msg.setType("ERROR");
271            msg.setException(e);
272            msg.setMessage(info);
273            msg.setComponent(component);
274            return createComponentMessage(msg);
275        }
276        
277        public static Element createComponentWarning(String task, String component, String info, Exception e) {
278            ManagementSupport.Message msg = new ManagementSupport.Message();
279            msg.setTask(task);
280            msg.setResult("SUCCESS");
281            msg.setType("WARNING");
282            msg.setException(e);
283            msg.setMessage(info);
284            msg.setComponent(component);
285            return createComponentMessage(msg);
286        }
287        
288    }