001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.sun.manager.jbi.management;
043:
044: import java.io.File;
045: import java.io.FileReader;
046: import java.io.StringReader;
047: import java.util.List;
048: import java.util.ArrayList;
049: import javax.xml.parsers.DocumentBuilder;
050: import javax.xml.parsers.DocumentBuilderFactory;
051: import javax.xml.xpath.XPath;
052: import javax.xml.xpath.XPathConstants;
053: import javax.xml.xpath.XPathExpressionException;
054: import javax.xml.xpath.XPathFactory;
055: import org.openide.DialogDisplayer;
056: import org.openide.NotifyDescriptor;
057: import org.w3c.dom.Document;
058: import org.w3c.dom.Node;
059: import org.w3c.dom.NodeList;
060: import org.xml.sax.InputSource;
061:
062: /**
063: *
064: * @author jqian
065: */
066: public class JBIMBeanTaskResultHandler {
067:
068: static final String LINE_SEPARATOR = System
069: .getProperty("line.separator"); // NOI18N
070:
071: /**
072: * @param actionName remote action name
073: * @param target action target (JBI component name,
074: * service assembly name, or the artifact)
075: * @param result remote invocation result
076: *
077: * @return <code>true</code> if the action is a complete success;
078: * <code>false</code> if it is a failure or a partial success.
079: */
080: public static boolean showRemoteInvokationResult(String actionName,
081: String target, String result) {
082: Object[] value = getProcessResult(actionName, target, result,
083: true);
084: String message = (String) value[0];
085: boolean failed = !((Boolean) value[1]);
086: if (message != null) {
087: int msgType = failed ? NotifyDescriptor.ERROR_MESSAGE
088: : NotifyDescriptor.WARNING_MESSAGE;
089: NotifyDescriptor d = new NotifyDescriptor.Message(message,
090: msgType);
091: DialogDisplayer.getDefault().notify(d);
092: }
093:
094: return message == null; // complete success
095: // !failed; // partial success
096: }
097:
098: /**
099: * @param actionName remote action name
100: * @param target action target (JBI component name,
101: * service assembly name, or the artifact)
102: * @param result remote invocation result
103: * @param html <code>true</code> to produce message in HTML;
104: * <code>false</code> otherwise.
105: *
106: * @return a two-object array; the first one (String) being the error
107: * message if there is a failure or partial success, it would
108: * be null if it is a complete success; the second one (Boolean)
109: * indicate whether it is a partial success.
110: */
111: public static Object[] getProcessResult(String actionName,
112: String target, String result, boolean html) {
113:
114: if (result == null || result.trim().length() == 0) {
115: return new Object[] { null, true };
116: }
117:
118: StringBuffer msg = new StringBuffer();
119:
120: if (html) {
121: msg = msg.append("<html><table width=\"800\"> <tr><td>"); // NOI18N
122: }
123:
124: boolean failed = false;
125:
126: if (result.indexOf("<?xml") == -1) { // NOI18N
127: // No XML, certain exception (IO) occurred during invoke()
128: if (result.indexOf("Exception") == -1) { // NOI18N
129: return new Object[] { null, true };
130: } else {
131: failed = true;
132: msg = msg.append(result);
133: }
134: } else {
135: String lineSeparator = System.getProperty("line.separator"); // NOI18N
136:
137: // Need to extract info from the XML result
138: result = result.substring(result.indexOf("<?xml")); // NOI18N
139: Document document = getDocument(result);
140:
141: failed = !JBIMBeanTaskResultHandler
142: .isFrameworkTaskResultSuccessful(document);
143:
144: List<TaskResult> frameworkTaskResults = JBIMBeanTaskResultHandler
145: .getTaskResultProblems(document, true);
146:
147: if (failed) {
148: msg = msg.append("Failed execution of "); // NOI18N
149: } else {
150: // complete or partial success, can't determine yet
151: // See the example in IZ #108114
152: msg = msg.append("Successful execution of "); // NOI18N
153: }
154:
155: msg = msg.append(actionName);
156: msg = msg.append(": "); // NOI18N
157: msg = msg.append(target);
158:
159: List<TaskResult> componentTaskResults = JBIMBeanTaskResultHandler
160: .getTaskResultProblems(document, false);
161:
162: if (!failed && componentTaskResults.size() == 0) {
163: // complete success
164: return new Object[] { null, true };
165: }
166:
167: if (html) {
168: for (TaskResult frameworkTaskResult : frameworkTaskResults) {
169: msg = msg.append("<br>");
170: msg = msg
171: .append(frameworkTaskResult.toHtmlString());
172: }
173:
174: msg = msg.append("<ul>");
175: for (TaskResult componentTaskResult : componentTaskResults) {
176: msg = msg
177: .append(componentTaskResult.toHtmlString());
178: }
179:
180: msg = msg.append("</ul>"); // NOI18N
181: msg = msg.append("</td></tr></table></html>"); // NOI18N
182:
183: } else {
184: for (TaskResult frameworkTaskResult : frameworkTaskResults) {
185: msg = msg.append(lineSeparator);
186: msg = msg.append(frameworkTaskResult);
187: }
188:
189: for (TaskResult componentTaskResult : componentTaskResults) {
190: msg = msg.append(lineSeparator);
191: msg = msg.append(componentTaskResult);
192: }
193: }
194: }
195:
196: return new Object[] { msg.toString(), !failed };
197: }
198:
199: public static boolean isFrameworkTaskResultSuccessful(
200: Document document) {
201: XPathFactory xpathFactory = XPathFactory.newInstance();
202: XPath xpath = xpathFactory.newXPath();
203:
204: try {
205: String frameworkTaskResult = xpath
206: .evaluate(
207: "//frmwk-task-result/frmwk-task-result-details/task-result-details/task-result/text()",
208: document); // NOI18N
209: return frameworkTaskResult.equals("SUCCESS"); // NOI18N
210: } catch (XPathExpressionException ex) {
211: ex.printStackTrace();
212: }
213:
214: return false;
215: }
216:
217: static List<TaskResult> getTaskResultProblems(Document document,
218: boolean framework) {
219: List<TaskResult> ret = new ArrayList<TaskResult>();
220:
221: ret.addAll(getTaskResultExceptions(document, framework));
222: ret.addAll(getTaskResultErrors(document, framework));
223: ret.addAll(getTaskResultWarnings(document, framework));
224: ret.addAll(getTaskResultInfos(document, framework));
225:
226: return ret;
227: }
228:
229: static List<TaskResult> getTaskResultExceptions(Document document,
230: boolean framework) {
231: String expression = getMyXPathExpression("EXCEPTION", framework); // NOI18N
232: return getMsgLocInfoOfType("ERROR", document, expression,
233: framework); // NOI18N
234: }
235:
236: static List<TaskResult> getTaskResultErrors(Document document,
237: boolean framework) {
238: String expression = getMyXPathExpression("ERROR", framework); // NOI18N
239: return getMsgLocInfoOfType("ERROR", document, expression,
240: framework); // NOI18N
241: }
242:
243: static List<TaskResult> getTaskResultWarnings(Document document,
244: boolean framework) {
245: String expression = getMyXPathExpression("WARNING", framework); // NOI18N
246: return getMsgLocInfoOfType("WARNING", document, expression,
247: framework); // NOI18N
248: }
249:
250: static List<TaskResult> getTaskResultInfos(Document document,
251: boolean framework) {
252: String expression = getMyXPathExpression("INFO", framework); // NOI18N
253: return getMsgLocInfoOfType("INFO", document, expression,
254: framework); // NOI18N
255: }
256:
257: private static String getMyXPathExpression(String messageType,
258: boolean framework) {
259: String ret = null;
260:
261: String taskResult = framework ? "frmwk-task-result"
262: : "component-task-result"; // NOI18N
263: if (messageType.equals("EXCEPTION")) { // NOI18N
264: ret = "//"
265: + taskResult
266: + "/*/task-result-details/exception-info/msg-loc-info"; // NOI18N
267: } else {
268: ret = "//" + taskResult
269: + "/*/task-result-details[message-type='"
270: + messageType + "']/task-status-msg/msg-loc-info"; // NOI18N
271: }
272:
273: return ret;
274: }
275:
276: private static List<TaskResult> getMsgLocInfoOfType(String type,
277: Document document, String expression, boolean framework) {
278:
279: List<TaskResult> ret = new ArrayList<TaskResult>();
280:
281: try {
282: XPathFactory xpathFactory = XPathFactory.newInstance();
283: XPath xpath = xpathFactory.newXPath();
284:
285: NodeList msgLocInfoNodeList = (NodeList) xpath.evaluate(
286: expression, document, XPathConstants.NODESET);
287:
288: if (msgLocInfoNodeList != null) {
289: int length = msgLocInfoNodeList.getLength();
290: for (int i = 0; i < length; i++) {
291: Node msgLocInfoNode = msgLocInfoNodeList.item(i);
292: String locTokenValue = xpath.evaluate(
293: "loc-token/text()", msgLocInfoNode); // NOI18N
294: String locMessageValue = xpath.evaluate(
295: "loc-message/text()", msgLocInfoNode); // NOI18N
296:
297: if (locTokenValue != null
298: || locMessageValue != null) {
299:
300: if (framework) {
301: ret.add(new TaskResult(type, locTokenValue,
302: locMessageValue));
303: } else {
304: Node parent = msgLocInfoNode;
305: while (!parent.getNodeName().equals(
306: "component-task-result")) { // NOI18N
307: parent = parent.getParentNode();
308: }
309: String componentName = xpath.evaluate(
310: "component-name/text()", parent); // NOI18N
311:
312: ret.add(new ComponentTaskResult(type,
313: locTokenValue, locMessageValue,
314: componentName));
315: }
316: }
317: }
318: }
319: } catch (XPathExpressionException e) {
320: e.printStackTrace();
321: }
322:
323: return ret;
324: }
325:
326: private static Document getDocument(String xmlString) {
327: try {
328: DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
329: .newInstance();
330: DocumentBuilder documentBuilder = documentBuilderFactory
331: .newDocumentBuilder();
332: return documentBuilder.parse(new InputSource(
333: new StringReader(xmlString)));
334:
335: } catch (Exception e) {
336: System.out.println("Error parsing XML string: " + e); // NOI18N
337: return null;
338: }
339: }
340:
341: public static Document getDocument(File xmlFile) {
342: try {
343: DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
344: .newInstance();
345: DocumentBuilder documentBuilder = documentBuilderFactory
346: .newDocumentBuilder();
347: return documentBuilder.parse(new InputSource(
348: new FileReader(xmlFile)));
349: } catch (Exception e) {
350: System.out.println("Error parsing XML file: " + e); // NOI18N
351: return null;
352: }
353: }
354: }
355:
356: class TaskResult {
357: private String messageType;
358: private String locToken;
359: private String locMessage;
360:
361: TaskResult(String messageType, String locToken, String locMessage) {
362: this .messageType = messageType;
363: this .locToken = locToken;
364: this .locMessage = locMessage;
365: }
366:
367: public String getMessageType() {
368: return messageType;
369: }
370:
371: public String getLocToken() {
372: return locToken;
373: }
374:
375: public String getLocMessage() {
376: return locMessage;
377: }
378:
379: public String toString() {
380: StringBuilder ret = new StringBuilder();
381:
382: ret = ret.append(getMessageType());
383: ret = ret.append(": ("); // NOI18N
384: ret = ret.append(getLocToken());
385: ret = ret.append(") "); // NOI18N
386: ret = ret.append(getLocMessage());
387:
388: return ret.toString();
389: }
390:
391: public String toHtmlString() {
392: StringBuilder ret = new StringBuilder();
393:
394: ret = ret.append("<b>"); // NOI18N
395: ret = ret.append(getMessageType());
396: ret = ret.append("</b>"); // NOI18N
397: ret = ret.append(": ("); // NOI18N
398: ret = ret.append(getLocToken());
399: ret = ret.append(") "); // NOI18N
400: ret = ret.append(getLocMessage().replaceAll("\n", "<br>") // NOI18N // See IZ #108114
401: .replaceAll("\t", " ")); // NOI18N
402:
403: return ret.toString();
404: }
405: }
406:
407: class ComponentTaskResult extends TaskResult {
408: private String componentName;
409:
410: ComponentTaskResult(String messageType, String locToken,
411: String locMessage, String componentName) {
412: super (messageType, locToken, locMessage);
413: this .componentName = componentName;
414: }
415:
416: public String getComponentName() {
417: return componentName;
418: }
419:
420: public String toString() {
421: StringBuilder ret = new StringBuilder();
422:
423: ret = ret.append(" * Component: "); // NOI18N
424: ret = ret.append(getComponentName());
425: ret = ret.append(JBIMBeanTaskResultHandler.LINE_SEPARATOR);
426: ret = ret.append(" "); // NOI18N
427: ret = ret.append(super .toString());
428:
429: return ret.toString();
430: }
431:
432: public String toHtmlString() {
433: StringBuilder ret = new StringBuilder();
434:
435: ret = ret.append("<li>"); // NOI18N
436: ret = ret.append("Component: "); // NOI18N
437: ret = ret.append(getComponentName());
438: ret = ret.append("<br>"); // NOI18N
439: ret = ret.append(" "); // NOI18N
440: ret = ret.append(super .toHtmlString());
441: ret = ret.append("</li>"); // NOI18N
442:
443: return ret.toString();
444: }
445: }
|