0001: /*
0002: * BEGIN_HEADER - DO NOT EDIT
0003: *
0004: * The contents of this file are subject to the terms
0005: * of the Common Development and Distribution License
0006: * (the "License"). You may not use this file except
0007: * in compliance with the License.
0008: *
0009: * You can obtain a copy of the license at
0010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
0011: * See the License for the specific language governing
0012: * permissions and limitations under the License.
0013: *
0014: * When distributing Covered Code, include this CDDL
0015: * HEADER in each file and include the License file at
0016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
0017: * If applicable add the following below this CDDL HEADER,
0018: * with the fields enclosed by brackets "[]" replaced with
0019: * your own identifying information: Portions Copyright
0020: * [year] [name of copyright owner]
0021: */
0022:
0023: /*
0024: * @(#)MessageBuilder.java
0025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
0026: *
0027: * END_HEADER - DO NOT EDIT
0028: */
0029: /**
0030: * MessageBuilder.java
0031: *
0032: * SUN PROPRIETARY/CONFIDENTIAL.
0033: * This software is the proprietary information of Sun Microsystems, Inc.
0034: * Use is subject to license terms.
0035: *
0036: * Created on August 23, 2006, 5:17 PM
0037: */package com.sun.jbi.management.message;
0038:
0039: import com.sun.jbi.ServiceUnitInfo;
0040: import com.sun.jbi.StringTranslator;
0041: import com.sun.jbi.management.ComponentMessageHolder;
0042: import com.sun.jbi.management.system.ManagementException;
0043:
0044: import java.io.StringReader;
0045: import java.util.logging.Logger;
0046: import java.util.ArrayList;
0047: import java.util.HashMap;
0048: import java.util.List;
0049: import java.util.Map;
0050: import java.util.Set;
0051:
0052: import javax.xml.bind.JAXBContext;
0053: import javax.xml.bind.JAXBException;
0054: import javax.xml.bind.Marshaller;
0055: import javax.xml.bind.Unmarshaller;
0056: import javax.xml.bind.Validator;
0057: import javax.xml.parsers.SAXParser;
0058: import javax.xml.parsers.SAXParserFactory;
0059:
0060: import javax.xml.transform.stream.StreamSource;
0061: import org.xml.sax.InputSource;
0062: import org.xml.sax.helpers.DefaultHandler;
0063:
0064: /**
0065: * Helper class to create Management messages
0066: *
0067: * @author Sun Microsystems, Inc.
0068: */
0069: public class MessageBuilder {
0070: public enum TaskResult {
0071: SUCCESS, FAILED
0072: };
0073:
0074: public enum MessageType {
0075: ERROR, WARNING, INFO
0076: };
0077:
0078: // Used to determine if result messages are well-formed xml
0079: private static SAXParser sXmlParser;
0080:
0081: private ObjectFactory mObjFactory;
0082: private Marshaller mWriter;
0083: private Unmarshaller mReader;
0084: private JAXBContext mJaxbContext;
0085: private StringTranslator mTranslator;
0086: private StringTranslator mLocalTranslator;
0087: private Logger mLog;
0088:
0089: private static final String TOKEN_PREFIX = "JBI";
0090: private static final String JBIMA0000 = "JBIMA0000";
0091: private static final String JBI_INSTANCE_NAME = "JBI_INSTANCE_NAME";
0092:
0093: /**
0094: * Message class encapsulates the JbiTask message, two accessors provide the
0095: * message string and information on whether the message is a success or failure.
0096: */
0097: public class Message {
0098: private JbiTaskResult mTaskMsg;
0099:
0100: public Message(JbiTask task) {
0101: mTaskMsg = task;
0102: }
0103:
0104: public Message(String jbiTaskMsg) throws ManagementException {
0105: mTaskMsg = getJbiTaskFromString(jbiTaskMsg);
0106: }
0107:
0108: /**
0109: * @return true if the TaskResult == SUCCESS, false otherwise
0110: */
0111: public boolean isSuccess() {
0112: JbiTaskResultElement jbiTaskMsgType = mTaskMsg
0113: .getJbiTaskResult();
0114:
0115: String taskResult = jbiTaskMsgType.getFrmwkTaskResult()
0116: .getFrmwkTaskResultDetails().getTaskResultDetails()
0117: .getTaskResult();
0118:
0119: if (TaskResult.SUCCESS == TaskResult.valueOf(taskResult)) {
0120: return true;
0121: } else {
0122: return false;
0123: }
0124: }
0125:
0126: /**
0127: * @return true if the TaskResult == FAILURE, false otherwise
0128: */
0129: public boolean isFailure() {
0130: JbiTaskResultElement jbiTaskMsgType = mTaskMsg
0131: .getJbiTaskResult();
0132:
0133: String taskResult = jbiTaskMsgType.getFrmwkTaskResult()
0134: .getFrmwkTaskResultDetails().getTaskResultDetails()
0135: .getTaskResult();
0136:
0137: if (TaskResult.FAILED == TaskResult.valueOf(taskResult)) {
0138: return true;
0139: } else {
0140: return false;
0141: }
0142: }
0143:
0144: /**
0145: * @return true if the TaskResult == SUCCESS and MsgType == WARNING, false otherwise
0146: */
0147: public boolean isSuccessWithWarning() {
0148: boolean isSuccess = false;
0149: boolean isWarning = false;
0150:
0151: JbiTaskResultElement jbiTaskMsgType = mTaskMsg
0152: .getJbiTaskResult();
0153:
0154: String taskResult = jbiTaskMsgType.getFrmwkTaskResult()
0155: .getFrmwkTaskResultDetails().getTaskResultDetails()
0156: .getTaskResult();
0157:
0158: if (TaskResult.SUCCESS == TaskResult.valueOf(taskResult)) {
0159: isSuccess = true;
0160: }
0161:
0162: String msgType = jbiTaskMsgType.getFrmwkTaskResult()
0163: .getFrmwkTaskResultDetails().getTaskResultDetails()
0164: .getMessageType();
0165:
0166: if (MessageType.WARNING == MessageType.valueOf(msgType)) {
0167: isWarning = true;
0168: }
0169:
0170: return (isSuccess && isWarning);
0171: }
0172:
0173: public String getMessage() throws ManagementException {
0174: return getString(mTaskMsg);
0175: }
0176: }
0177:
0178: private synchronized ObjectFactory getObjectFactory()
0179: throws JAXBException {
0180: if (mObjFactory == null) {
0181: mObjFactory = new ObjectFactory();
0182: }
0183:
0184: return mObjFactory;
0185: }
0186:
0187: /**
0188: * Create a message
0189: * @param jbiTaskMsg - task message string
0190: * @return created Message
0191: * @throws ManagementException
0192: */
0193: public Message createMessage(String jbiTaskMsg)
0194: throws ManagementException {
0195: return new Message(jbiTaskMsg);
0196: }
0197:
0198: public MessageBuilder(com.sun.jbi.StringTranslator translator)
0199: throws ManagementException {
0200: try {
0201: mTranslator = translator;
0202: mLocalTranslator = com.sun.jbi.util.EnvironmentAccess
0203: .getContext().getStringTranslator(
0204: "com.sun.jbi.management");
0205:
0206: mLog = Logger.getLogger("com.sun.jbi.management");
0207: } catch (Exception ex) {
0208: throw new ManagementException(ex);
0209: }
0210: }
0211:
0212: /**
0213: * Build a simple framework task message based on the passed
0214: * parameters and return the string.
0215: */
0216: public String buildFrameworkMessage(String taskId,
0217: TaskResult taskResult, List<ComponentMessageHolder> compMsgs)
0218: throws ManagementException {
0219: return buildFrameworkMessage(taskId, taskResult, null, null,
0220: new String[0], null, compMsgs);
0221: }
0222:
0223: /**
0224: * Build a simple framework task message based on the passed
0225: * parameters and return the string.
0226: */
0227: public String buildFrameworkMessage(String taskId,
0228: TaskResult taskResult) throws ManagementException {
0229: return buildFrameworkMessage(taskId, taskResult, null, null,
0230: new String[0], null);
0231: }
0232:
0233: /**
0234: * Build a Framework Message with component task results
0235: */
0236: public String buildFrameworkMessage(String taskId,
0237: TaskResult taskResult, MessageType messageType,
0238: String message, String[] params, String token,
0239: List<ComponentMessageHolder> compMsgs)
0240: throws ManagementException {
0241: try {
0242: message = getMessageString(message);
0243:
0244: JbiTask jbiTaskMsg = buildTaskMsg(taskId, taskResult,
0245: messageType, message, params, token);
0246:
0247: if (!compMsgs.isEmpty()) {
0248: appendComponentTaskResult(jbiTaskMsg, compMsgs);
0249: }
0250:
0251: return getString(jbiTaskMsg);
0252: } catch (JAXBException jex) {
0253: throw new ManagementException(jex);
0254: }
0255: }
0256:
0257: /**
0258: * Build a simple framework task message based on the passed
0259: * parameters and return the string.
0260: */
0261: public String buildFrameworkMessage(String taskId,
0262: TaskResult taskResult, MessageType messageType,
0263: String message, String[] params, String token)
0264: throws ManagementException {
0265: List<ComponentMessageHolder> compMsgs = new ArrayList<ComponentMessageHolder>();
0266:
0267: return buildFrameworkMessage(taskId, taskResult, messageType,
0268: message, params, token, compMsgs);
0269: };
0270:
0271: /**
0272: * Build a framework task message with exception. If the exception message is a
0273: * jbi task message or a jbi localized message the message is returned as is.
0274: *
0275: * @param taskId - name of the operation which threw the exception
0276: * @param ex - the exception
0277: */
0278: public String buildExceptionMessage(String taskId, Throwable ex)
0279: throws ManagementException {
0280: try {
0281: String exMessage = ex.getMessage();
0282: if (exMessage != null) {
0283: if (isXmlString(exMessage)) {
0284: return exMessage;
0285: }
0286: }
0287:
0288: JbiTask taskMsg = null;
0289: if (isLocalizedMessage(exMessage)) {
0290: taskMsg = buildTaskMsg(taskId, TaskResult.FAILED,
0291: MessageType.ERROR, getMessageString(ex
0292: .getMessage()), new String[0],
0293: getMessageToken(exMessage));
0294: ex = ex.getCause();
0295: } else {
0296: taskMsg = buildTaskMsg(taskId, TaskResult.FAILED,
0297: MessageType.ERROR, ex.getMessage(),
0298: new String[0], null);
0299: }
0300:
0301: // -- Append Exception Info
0302: if (ex != null) {
0303: List<ExceptionInfo> exList = taskMsg.getJbiTaskResult()
0304: .getFrmwkTaskResult()
0305: .getFrmwkTaskResultDetails()
0306: .getTaskResultDetails().getExceptionInfo();
0307: appendExceptionInfo(exList, ex);
0308: ex.printStackTrace();
0309: }
0310: return getString(taskMsg);
0311: } catch (JAXBException jex) {
0312: throw new ManagementException(jex);
0313: }
0314: }
0315:
0316: /**
0317: * @return the stack trace of the exception object as a string
0318: */
0319: public String getStackTrace(Throwable exObj) {
0320: StackTraceElement[] stckTrElem = exObj.getStackTrace();
0321: StringBuffer sb = new StringBuffer("");
0322: if (stckTrElem != null) {
0323: for (int i = 0; i < stckTrElem.length; i++) {
0324: String stckTrace = stckTrElem[i].toString();
0325: sb.append(stckTrace);
0326: sb.append("\n");
0327: }
0328: }
0329: return sb.toString();
0330: }
0331:
0332: /**
0333: * Get the string from the management message object.
0334: */
0335: public String getString(JbiTaskResult jbiTaskMsg)
0336: throws ManagementException {
0337: String message = null;
0338: if (jbiTaskMsg != null) {
0339: java.io.StringWriter sw = new java.io.StringWriter();
0340: try {
0341: marshal(jbiTaskMsg, sw);
0342: message = sw.toString();
0343: } catch (Exception ex) {
0344: throw new ManagementException(ex);
0345: } finally {
0346: try
0347:
0348: {
0349: sw.close();
0350: } catch (java.io.IOException ioex) {
0351:
0352: }
0353: }
0354:
0355: }
0356: return message;
0357: }
0358:
0359: /** Returns the JBIMAxxxx mesage token from a localized message entry. */
0360: public static String getMessageToken(String message) {
0361: // -- Get the token only if one exists else return JBIMA0000
0362: if (isLocalizedMessage(message) && message.length() >= 9) {
0363: return message.substring(0, 9);
0364: } else {
0365: return JBIMA0000;
0366: }
0367: }
0368:
0369: /** Returns the string from a message entry without the JBIMAxxxx token. */
0370: public static String getMessageString(String message) {
0371: if (isLocalizedMessage(message)) {
0372: if (message.length() >= 12) {
0373: return message.substring(11);
0374: } else {
0375: // Message which has a token but no message string
0376: return "";
0377: }
0378: } else {
0379: return message;
0380: }
0381: }
0382:
0383: public void throwManagementException(String taskId, String msgKey,
0384: String[] params) throws ManagementException {
0385: String message = mTranslator.getString(msgKey, params);
0386: String response = buildFrameworkMessage(taskId,
0387: TaskResult.FAILED, MessageType.ERROR,
0388: getMessageString(message), params,
0389: getMessageToken(message));
0390: mLog.warning(response);
0391: throw new ManagementException(response);
0392: }
0393:
0394: /**
0395: * Parse the Component Results. This is based on the fact that the
0396: * ServiceUnitList obtained from a ServiceAssemblyInfo and the ComponentTaskResults
0397: * follow the document order of the ServiceUnits in the Service Assembly jbi.xml.
0398: *
0399: * The DeploymentService should also append a ComponentTaskResult for each Service
0400: * Unit in the Service Assembly.
0401: */
0402: public List<ServiceUnitInfo> getSuccessfulServiceUnits(
0403: String jbiTaskMsg, List<ServiceUnitInfo> suInfoList)
0404: throws ManagementException {
0405: List<ServiceUnitInfo> suList = new ArrayList<ServiceUnitInfo>();
0406:
0407: JbiTask jbiTask = getJbiTaskFromString(jbiTaskMsg);
0408:
0409: if (jbiTask != null) {
0410: List<ComponentTaskResult> compResults = jbiTask
0411: .getJbiTaskResult().getComponentTaskResult();
0412:
0413: int i = 0;
0414:
0415: for (ComponentTaskResult compResult : compResults) {
0416: TaskResultDetailsElement taskDetails = ((TaskResultDetails) compResult
0417: .getComponentTaskResultDetails())
0418: .getTaskResultDetails();
0419:
0420: String taskResult = taskDetails.getTaskResult();
0421: if (TaskResult.SUCCESS == TaskResult
0422: .valueOf(taskResult)) {
0423: boolean matchFound = false;
0424: ServiceUnitInfo suInfo = null;
0425: while (!matchFound && i < suInfoList.size()) {
0426: suInfo = suInfoList.get(i++);
0427: if (!suInfo.getTargetComponent().equals(
0428: compResult.getComponentName())) {
0429:
0430: String[] params = new String[] {
0431: suInfo.getName(),
0432: suInfo.getTargetComponent() };
0433: String wrnMsg = mLocalTranslator
0434: .getString(
0435: com.sun.jbi.management.LocalStringKeys.DS_SU_OP_FAILED,
0436: params);
0437: mLog.warning(wrnMsg);
0438: continue;
0439: } else {
0440: matchFound = true;
0441: }
0442: }
0443: if (matchFound) {
0444: suList.add(suInfo);
0445: }
0446: }
0447: }
0448: }
0449: return suList;
0450: }
0451:
0452: /**
0453: * This method composes a JBI Task Message from the exceptions in the Map. In
0454: * cases of complete failure what we get back from the remote instance is an
0455: * exception, which ( hopefully ) has a jbi task message as the message. If the
0456: * exceptions message is not a jbi task message, then this will build a jbi task
0457: * message from it.
0458: *
0459: * This composition is required only in the complete failure cases.
0460: *
0461: * @param exceptionMap - a map keyed by the instance names and the value is the
0462: * exception thrown by the remote instance with the MBean exceptions stripped off.
0463: * @return a composite JBI Task message that has all the information.
0464: *
0465: */
0466: public String buildCompositeExceptionMessage(String taskId,
0467: java.util.Map<String, Throwable> exceptionMap)
0468: throws ManagementException {
0469:
0470: List<ExceptionInfo> exceptions = new ArrayList<ExceptionInfo>();
0471: List<TaskStatusMsg> taskMsgs = new ArrayList<TaskStatusMsg>();
0472: List<TaskResult> taskResults = new ArrayList<TaskResult>();
0473: List<MessageType> msgTypes = new ArrayList<MessageType>();
0474:
0475: java.util.Set<String> instances = exceptionMap.keySet();
0476: try {
0477: for (String instance : instances) {
0478: Exception ex = (Exception) exceptionMap.get(instance);
0479:
0480: JbiTask jbiTask = getJbiTaskMessage(taskId, ex);
0481:
0482: taskResults.add(getTaskResult(jbiTask));
0483:
0484: MessageType msgType = getMessageType(jbiTask);
0485: if (msgType != null) {
0486: msgTypes.add(msgType);
0487: }
0488:
0489: List<TaskStatusMsg> instTaskMsgs = getTaskStatusMsgs(jbiTask);
0490:
0491: if (!instTaskMsgs.isEmpty()) {
0492: // -- Add the marker instance status message
0493: taskMsgs.add(buildTaskStatusMsg(instance,
0494: JBI_INSTANCE_NAME, new String[0]));
0495: }
0496:
0497: List<ExceptionInfo> instExceptions = getExceptionInfos(jbiTask);
0498:
0499: if (!instExceptions.isEmpty()) {
0500: // -- Add the marker exception-info for the instance
0501: exceptions.add(buildExceptionInfo(instance,
0502: JBI_INSTANCE_NAME, new String[0]));
0503: }
0504:
0505: taskMsgs.addAll(instTaskMsgs);
0506: exceptions.addAll(instExceptions);
0507: }
0508:
0509: JbiTask compositeTask = null;
0510:
0511: compositeTask = buildTaskMsg(taskId,
0512: getEffectiveTaskResult(taskResults, true),
0513: getEffectiveMessageType(msgTypes), null,
0514: new String[0], null);
0515:
0516: compositeTask = appendTaskMsgs(compositeTask, taskMsgs);
0517:
0518: compositeTask = appendExceptionInfos(compositeTask,
0519: exceptions);
0520: return getString(compositeTask);
0521: } catch (javax.xml.bind.JAXBException jex) {
0522: throw new ManagementException(jex);
0523: }
0524:
0525: }
0526:
0527: /**
0528: * This operation combines the data from exception jbi task messages and response
0529: * jbi task messages. The primary user of this operation is the facade DeploymentSvc.
0530: *
0531: * @param taskId - task id
0532: * @param responseMap - a map of jbi task message responses from instances.
0533: * @param exceptionMap - a map of exception task message from instances.
0534: * @param requireAllSuccess - this flag indicates how the result of component task
0535: * results for each component from various instances has to be handled. If set to true
0536: * a Component task result has a task result of SUCCESS only if all the ComponentTask
0537: * results in the response and exception maps are a success.
0538: */
0539: public Message buildCompositeMessage(String taskId,
0540: Map<String, String> responseMap,
0541: Map<String, Throwable> exceptionMap,
0542: boolean requireAllSuccess) throws ManagementException {
0543: List<ExceptionInfo> exceptions = new ArrayList<ExceptionInfo>();
0544: List<TaskStatusMsg> taskMsgs = new ArrayList<TaskStatusMsg>();
0545: ComponentInstanceResult[] compResultData = null;
0546:
0547: Map<String, JbiTask> jbiTasks = new HashMap<String, JbiTask>();
0548:
0549: List<TaskResult> rslts = new ArrayList<TaskResult>();
0550:
0551: if (!responseMap.isEmpty()) {
0552: java.util.Set<String> instances = responseMap.keySet();
0553: for (String instance : instances) {
0554: JbiTask jbiTask = getJbiTaskFromString(responseMap
0555: .get(instance));
0556: TaskResult rslt = TaskResult.valueOf(jbiTask
0557: .getJbiTaskResult().getFrmwkTaskResult()
0558: .getFrmwkTaskResultDetails()
0559: .getTaskResultDetails().getTaskResult());
0560: rslts.add(rslt);
0561: jbiTasks.put(instance, jbiTask);
0562: }
0563: }
0564:
0565: if (!exceptionMap.isEmpty()) {
0566: java.util.Set<String> instances = exceptionMap.keySet();
0567: for (String instance : instances) {
0568: Exception ex = (Exception) exceptionMap.get(instance);
0569:
0570: JbiTask jbiTask = getJbiTaskMessage(taskId, ex);
0571: TaskResult rslt = TaskResult.valueOf(jbiTask
0572: .getJbiTaskResult().getFrmwkTaskResult()
0573: .getFrmwkTaskResultDetails()
0574: .getTaskResultDetails().getTaskResult());
0575: rslts.add(rslt);
0576: jbiTasks.put(instance, jbiTask);
0577: }
0578: }
0579:
0580: JbiTask compositeTask = null;
0581: try {
0582: compResultData = extractMessageData(jbiTasks, taskMsgs,
0583: exceptions, compResultData);
0584:
0585: compositeTask = buildTaskMsg(taskId, TaskResult.FAILED,
0586: MessageType.ERROR, null, new String[0], null);
0587:
0588: compositeTask = appendTaskMsgs(compositeTask, taskMsgs);
0589:
0590: compositeTask = appendExceptionInfos(compositeTask,
0591: exceptions);
0592:
0593: List<ComponentTaskResult> compResults = buildComponentTaskResults(
0594: taskId, compResultData, requireAllSuccess);
0595: compositeTask = appendComponentTaskResult(compositeTask,
0596: compResults);
0597:
0598: for (ComponentTaskResult compResult : compResults) {
0599: TaskResult rslt = TaskResult.valueOf(compResult
0600: .getComponentTaskResultDetails()
0601: .getTaskResultDetails().getTaskResult());
0602: rslts.add(rslt);
0603: }
0604:
0605: // set the corrected task result
0606: TaskResult theResult = TaskResult.SUCCESS;
0607: if (!rslts.isEmpty()) {
0608: theResult = getEffectiveTaskResult(rslts,
0609: requireAllSuccess);
0610: } else {
0611: if (responseMap.isEmpty() && !exceptionMap.isEmpty()) {
0612: theResult = TaskResult.FAILED;
0613: }
0614: }
0615:
0616: if (TaskResult.SUCCESS == theResult) {
0617: TaskResultDetailsElement taskDetails = compositeTask
0618: .getJbiTaskResult().getFrmwkTaskResult()
0619: .getFrmwkTaskResultDetails()
0620: .getTaskResultDetails();
0621:
0622: taskDetails.setTaskResult(theResult.toString());
0623: MessageType type = getEffectiveMessageType(rslts,
0624: requireAllSuccess);
0625: taskDetails.setMessageType(type.toString());
0626: }
0627: return new Message(compositeTask);
0628: } catch (javax.xml.bind.JAXBException jex) {
0629: throw new ManagementException(jex);
0630: }
0631:
0632: }
0633:
0634: // -- This is the single op from the ManagementMessageBuilder Interface
0635: /**
0636: * Return an XML string of the component message(either status
0637: * or exception message).
0638: * @param msgObject component message holder object
0639: * @return Message as XML string
0640: * @throws Exception if unable to build message
0641: *
0642: */
0643: String buildComponentMessage(ComponentMessageHolder msgObject)
0644: throws Exception {
0645: return getString(buildComponentTaskResult(msgObject));
0646: }
0647:
0648: /**
0649: * This method is used to check if the given string contains well-formed
0650: * XML.
0651: * @param str the string
0652: * @return true if the given string is xml
0653: */
0654: public static boolean isXmlString(String str) {
0655: boolean isXmlString = false;
0656:
0657: // make sure there is something to validate and there is something to
0658: // validate it with
0659: if (str != null) {
0660: try {
0661: if (sXmlParser == null) {
0662: sXmlParser = SAXParserFactory.newInstance()
0663: .newSAXParser();
0664: }
0665: synchronized (sXmlParser) {
0666: sXmlParser.parse(new InputSource(new StringReader(
0667: str)), new DefaultHandler());
0668: }
0669:
0670: isXmlString = true;
0671: } catch (Exception ex) {
0672: // This is expected in cases where the result is not XML
0673: }
0674: }
0675:
0676: return isXmlString;
0677: }
0678:
0679: /**
0680: * @return true if the message starts with JBIMA
0681: */
0682: public static boolean isLocalizedMessage(String message) {
0683: boolean isLocMsg = false;
0684:
0685: if (message != null) {
0686: // The message should be at least 9 chars long ( 1-9 - token)
0687: isLocMsg = (message.trim().startsWith(TOKEN_PREFIX) && message
0688: .length() >= 9);
0689: }
0690: return isLocMsg;
0691: }
0692:
0693: /*--------------------------------------------------------------------------------*\
0694: * Private Helpers *
0695: \*--------------------------------------------------------------------------------*/
0696:
0697: /**
0698: * Append ExceptionInfo's to the exception info list. An exception info is added
0699: * for each exception in the chain with a nesting level = number of exceptions
0700: * in the chain.
0701: */
0702: private void appendExceptionInfo(List<ExceptionInfo> exList,
0703: Throwable ex) throws JAXBException {
0704: int nestingLevel = 1;
0705: while (ex != null) {
0706: ExceptionInfo exInfo = getObjectFactory()
0707: .createExceptionInfo();
0708:
0709: exInfo.setNestingLevel(String.valueOf(nestingLevel));
0710: /** The extends message could be a jbi localized message, we don't
0711: have the localized params, but atleast salvage the token */
0712: MsgLocInfo msgLocInfo = buildMsgLocInfo(getMessageString(ex
0713: .getMessage()), getMessageToken(ex.getMessage()),
0714: new String[0]);
0715: exInfo.setMsgLocInfo(msgLocInfo);
0716: exInfo.setStackTrace(getStackTrace(ex));
0717:
0718: // -- append the exception info
0719: exList.add(exInfo);
0720: nestingLevel += 1;
0721: ex = ex.getCause();
0722: }
0723: }
0724:
0725: /**
0726: * Append ExceptionInfo's to the exception info list for a Component Task result.
0727: * An exception info is added for each exception in the chain with a nesting level
0728: * = number of exceptions in the chain. If the loc message info is set in the
0729: * ComponentMessageHolder use that
0730: */
0731: private void appendExceptionInfo(List<ExceptionInfo> exList,
0732: Throwable ex, ComponentMessageHolder compMsg)
0733: throws JAXBException {
0734: int nestingLevel = 1;
0735: while (ex != null) {
0736: ExceptionInfo exInfo = getObjectFactory()
0737: .createExceptionInfo();
0738:
0739: exInfo.setNestingLevel(String.valueOf(nestingLevel));
0740:
0741: MsgLocInfo msgLocInfo = null;
0742: if (compMsg.getLocMessage(nestingLevel) != null) {
0743: msgLocInfo = buildMsgLocInfo(compMsg
0744: .getLocMessage(nestingLevel), compMsg
0745: .getLocToken(nestingLevel), compMsg
0746: .getLocParam(nestingLevel));
0747: } else {
0748: msgLocInfo = buildMsgLocInfo(ex.toString(), null,
0749: new String[0]);
0750: }
0751:
0752: exInfo.setMsgLocInfo(msgLocInfo);
0753:
0754: exInfo.setStackTrace(getStackTrace(ex));
0755:
0756: // -- append the exception info
0757: exList.add(exInfo);
0758: nestingLevel += 1;
0759: ex = ex.getCause();
0760: }
0761: }
0762:
0763: /**
0764: *
0765: */
0766: private JbiTask buildTaskMsg(String taskId, TaskResult taskResult,
0767: MessageType messageType, String message, String[] params,
0768: String token) throws JAXBException {
0769: JbiTask jbiTask = getObjectFactory().createJbiTask();
0770:
0771: JbiTaskResultElement jbiTaskMsgType = getObjectFactory()
0772: .createJbiTaskResultElement();
0773:
0774: FrmwkTaskResult fmwkTaskResult = getObjectFactory()
0775: .createFrmwkTaskResult();
0776:
0777: FrmwkTaskResultDetails fmwkTaskResultDetails = getObjectFactory()
0778: .createFrmwkTaskResultDetails();
0779:
0780: TaskResultDetailsElement taskResultDetails = getObjectFactory()
0781: .createTaskResultDetailsElement();
0782:
0783: taskResultDetails.setTaskId(taskId);
0784: taskResultDetails.setTaskResult(taskResult.toString());
0785:
0786: if (messageType != null) {
0787: taskResultDetails.setMessageType(messageType.toString());
0788: }
0789:
0790: // - Task Status Message
0791: if (message != null) {
0792: TaskStatusMsg taskStatusMsg = buildTaskStatusMsg(message,
0793: token, params);
0794:
0795: taskResultDetails.getTaskStatusMsg().add(taskStatusMsg);
0796: }
0797:
0798: fmwkTaskResultDetails.setLocale(java.util.Locale.getDefault()
0799: .toString());
0800:
0801: fmwkTaskResultDetails.setTaskResultDetails(taskResultDetails);
0802: fmwkTaskResult.setFrmwkTaskResultDetails(fmwkTaskResultDetails);
0803:
0804: jbiTaskMsgType.setFrmwkTaskResult(fmwkTaskResult);
0805: //jbiTaskMsg.setJbiTaskResult(jbiTaskMsgType);
0806:
0807: jbiTask.setJbiTaskResult(jbiTaskMsgType);
0808: jbiTask.setVersion(new java.math.BigDecimal("1.0"));
0809: return jbiTask;
0810: }
0811:
0812: /**
0813: * Build a general task-status-msg based on passed params.
0814: */
0815: private TaskStatusMsg buildTaskStatusMsg(String message,
0816: String token, String[] params) throws JAXBException {
0817:
0818: MsgLocInfo msgLocInfo = buildMsgLocInfo(message, token, params);
0819: TaskStatusMsg taskStatusMsg = getObjectFactory()
0820: .createTaskStatusMsg();
0821: taskStatusMsg.setMsgLocInfo(msgLocInfo);
0822:
0823: return taskStatusMsg;
0824: }
0825:
0826: /**
0827: * Build a general Exception info based on the passed params.
0828: */
0829: private ExceptionInfo buildExceptionInfo(String message,
0830: String token, String[] params) throws JAXBException {
0831: MsgLocInfo msgLocInfo = buildMsgLocInfo(message, token, params);
0832: ExceptionInfo exceptionInfo = getObjectFactory()
0833: .createExceptionInfo();
0834: exceptionInfo.setMsgLocInfo(msgLocInfo);
0835: exceptionInfo.setNestingLevel("0");
0836:
0837: return exceptionInfo;
0838: }
0839:
0840: /**
0841: * Build a MsgLocInfo based on the passed parameters
0842: */
0843: private MsgLocInfo buildMsgLocInfo(String message, String token,
0844: String[] params) throws JAXBException {
0845: MsgLocInfo msgLocInfo = getObjectFactory().createMsgLocInfo();
0846:
0847: msgLocInfo.setLocMessage(message);
0848:
0849: if (token != null) {
0850: msgLocInfo.setLocToken(token);
0851: } else {
0852: msgLocInfo.setLocToken(JBIMA0000);
0853: }
0854: java.util.List<String> locParams = msgLocInfo.getLocParam();
0855: for (String param : params) {
0856: locParams.add(param);
0857: }
0858:
0859: return msgLocInfo;
0860: }
0861:
0862: /**
0863: * Get the JbiTask Message JAXB object from the message string version
0864: */
0865: private JbiTask getJbiTaskFromString(String jbiTaskMsg)
0866: throws ManagementException {
0867: try {
0868: StringBuffer strBuf = new StringBuffer(jbiTaskMsg);
0869: return (JbiTask) unmarshal(new StreamSource(
0870: new java.io.StringReader(strBuf.toString())));
0871: } catch (Exception jex) {
0872: throw new ManagementException(jex);
0873: }
0874: }
0875:
0876: /**
0877: *
0878: */
0879: private JbiTask getJbiTaskMessage(String taskId, Exception ex)
0880: throws ManagementException {
0881: JbiTask jbiTask = null;
0882: if (isXmlString(ex.getMessage())) {
0883: jbiTask = getJbiTaskFromString(ex.getMessage());
0884: } else {
0885: try {
0886: jbiTask = buildTaskMsg(taskId, TaskResult.FAILED,
0887: MessageType.ERROR, ex.getMessage(),
0888: new String[0], null);
0889:
0890: // -- Append Exception Info
0891: List<ExceptionInfo> exList = jbiTask.getJbiTaskResult()
0892: .getFrmwkTaskResult()
0893: .getFrmwkTaskResultDetails()
0894: .getTaskResultDetails().getExceptionInfo();
0895: appendExceptionInfo(exList, ex);
0896: } catch (javax.xml.bind.JAXBException jex) {
0897: throw new ManagementException(jex);
0898: }
0899: }
0900:
0901: return jbiTask;
0902: }
0903:
0904: /**
0905: * Append Component Task results to the JbiTask message.
0906: *
0907: * @param
0908: */
0909: private void appendComponentTaskResult(JbiTask jbiTaskMsg,
0910: List<ComponentMessageHolder> compMsgs) throws JAXBException {
0911: if (jbiTaskMsg != null) {
0912: com.sun.jbi.management.message.JbiTaskResultElement taskResult = jbiTaskMsg
0913: .getJbiTaskResult();
0914:
0915: if (taskResult != null) {
0916: List<ComponentTaskResult> comTaskResults = taskResult
0917: .getComponentTaskResult();
0918:
0919: for (ComponentMessageHolder compMsg : compMsgs) {
0920: comTaskResults
0921: .add(buildComponentTaskResult(compMsg));
0922: }
0923: }
0924: }
0925: }
0926:
0927: /**
0928: * Build a Component Task Result from the ComponentMessageHolder
0929: */
0930: private ComponentTaskResult buildComponentTaskResult(
0931: ComponentMessageHolder compMsg) throws JAXBException {
0932: ComponentTaskResult compRslt = getObjectFactory()
0933: .createComponentTaskResult();
0934:
0935: compRslt.setComponentName(compMsg.getComponentName());
0936:
0937: TaskResultDetailsElement taskResultDetailsElement = getObjectFactory()
0938: .createTaskResultDetailsElement();
0939:
0940: TaskResultDetails taskResultDetails = getObjectFactory()
0941: .createTaskResultDetails();
0942:
0943: taskResultDetailsElement.setTaskId(compMsg.getTaskName());
0944: taskResultDetailsElement.setTaskResult(compMsg.getTaskResult());
0945:
0946: if (compMsg.getStatusMessageType() != null) {
0947: taskResultDetailsElement
0948: .setMessageType(MessageType.valueOf(
0949: compMsg.getStatusMessageType()).toString());
0950: }
0951:
0952: // - Task Status Message
0953: // -- ComponentMessageHolder does not accomodate TaskStatusMsg !!
0954:
0955: // -- Exception Info
0956: if (compMsg.getExceptionObject() != null) {
0957: appendExceptionInfo(taskResultDetailsElement
0958: .getExceptionInfo(), compMsg.getExceptionObject(),
0959: compMsg);
0960: }
0961: taskResultDetails
0962: .setTaskResultDetails(taskResultDetailsElement);
0963: compRslt.setComponentTaskResultDetails(taskResultDetails);
0964:
0965: return compRslt;
0966: }
0967:
0968: /**
0969: * Get the String for the ComponentTaskResult
0970: */
0971: /**
0972: * Get the string from the management message object.
0973: */
0974: private String getString(ComponentTaskResult compTaskResult)
0975: throws ManagementException {
0976: String message = null;
0977: if (compTaskResult != null) {
0978: java.io.StringWriter sw = new java.io.StringWriter();
0979: try {
0980: marshal(compTaskResult, sw);
0981: message = sw.toString();
0982: } catch (Exception ex) {
0983: throw new ManagementException(ex);
0984: } finally {
0985: try
0986:
0987: {
0988: sw.close();
0989: } catch (java.io.IOException ioex) {
0990:
0991: }
0992: }
0993: }
0994: return message;
0995: }
0996:
0997: private List<TaskStatusMsg> getTaskStatusMsgs(JbiTask jbiTask) {
0998: return jbiTask.getJbiTaskResult().getFrmwkTaskResult()
0999: .getFrmwkTaskResultDetails().getTaskResultDetails()
1000: .getTaskStatusMsg();
1001: }
1002:
1003: private List<ExceptionInfo> getExceptionInfos(JbiTask jbiTask) {
1004: return jbiTask.getJbiTaskResult().getFrmwkTaskResult()
1005: .getFrmwkTaskResultDetails().getTaskResultDetails()
1006: .getExceptionInfo();
1007:
1008: }
1009:
1010: /**
1011: * Append the list of task status messages to the framework task result details.
1012: */
1013: private JbiTask appendTaskMsgs(JbiTask jbiTask,
1014: List<TaskStatusMsg> taskMsgs) {
1015: TaskResultDetailsElement details = jbiTask.getJbiTaskResult()
1016: .getFrmwkTaskResult().getFrmwkTaskResultDetails()
1017: .getTaskResultDetails();
1018:
1019: for (TaskStatusMsg taskMsg : taskMsgs) {
1020: details.getTaskStatusMsg().add(taskMsg);
1021: }
1022:
1023: return jbiTask;
1024: }
1025:
1026: /**
1027: * Append the list of exception infos to the framework task result details.
1028: */
1029: private JbiTask appendExceptionInfos(JbiTask jbiTask,
1030: List<ExceptionInfo> exceptions)
1031:
1032: {
1033: TaskResultDetailsElement details = jbiTask.getJbiTaskResult()
1034: .getFrmwkTaskResult().getFrmwkTaskResultDetails()
1035: .getTaskResultDetails();
1036:
1037: for (ExceptionInfo exInfo : exceptions) {
1038: details.getExceptionInfo().add(exInfo);
1039: }
1040:
1041: return jbiTask;
1042: }
1043:
1044: /**
1045: * For each component in compResultData, build a single ComponentTaskResult with
1046: * all the task status msgs and exception infos from all the TaskResultDetails
1047: * for the component.
1048: *
1049: * If requireAllSuccess is true then the ComponentTaskResult has a status of SUCCESS
1050: * if all TaskResultDetails have a SUCCESS task result.
1051: */
1052: private List<ComponentTaskResult> buildComponentTaskResults(
1053: String taskId, ComponentInstanceResult[] compResultData,
1054: boolean requireAllSuccess) throws JAXBException {
1055: List<ComponentTaskResult> compResults = new ArrayList<ComponentTaskResult>();
1056:
1057: List<TaskResult> taskResults = new ArrayList<TaskResult>();
1058:
1059: for (ComponentInstanceResult compInstResult : compResultData) {
1060: ComponentTaskResult compRslt = getObjectFactory()
1061: .createComponentTaskResult();
1062:
1063: compRslt
1064: .setComponentName(compInstResult.getComponentName());
1065:
1066: TaskResultDetailsElement taskResultDetails = getObjectFactory()
1067: .createTaskResultDetailsElement();
1068:
1069: taskResultDetails.setTaskId(taskId);
1070:
1071: Map compInstanceDetails = (Map) compInstResult
1072: .getInstanceResults();
1073:
1074: Set<String> instances = compInstanceDetails.keySet();
1075:
1076: for (String instance : instances) {
1077: TaskResultDetailsElement details = (TaskResultDetailsElement) compInstanceDetails
1078: .get(instance);
1079:
1080: // Get the task status msg and any exception infos from the component
1081: // task result details
1082: List<TaskStatusMsg> instTaskMsgs = details
1083: .getTaskStatusMsg();
1084: if (!instTaskMsgs.isEmpty()) {
1085: taskResultDetails.getTaskStatusMsg().add(
1086: buildTaskStatusMsg(instance,
1087: JBI_INSTANCE_NAME, new String[0]));
1088: }
1089: taskResultDetails.getTaskStatusMsg().addAll(
1090: instTaskMsgs);
1091:
1092: List<ExceptionInfo> instExceptions = details
1093: .getExceptionInfo();
1094: if (!instExceptions.isEmpty()) {
1095: taskResultDetails.getExceptionInfo().add(
1096: buildExceptionInfo(instance,
1097: JBI_INSTANCE_NAME, new String[0]));
1098:
1099: }
1100: taskResultDetails.getExceptionInfo().addAll(
1101: instExceptions);
1102: taskResults.add(TaskResult.valueOf(details
1103: .getTaskResult()));
1104: }
1105:
1106: TaskResult rslt = getEffectiveTaskResult(taskResults,
1107: requireAllSuccess);
1108: taskResultDetails.setTaskResult(rslt.toString());
1109: MessageType type = getEffectiveMessageType(taskResults,
1110: requireAllSuccess);
1111: taskResultDetails.setMessageType(type.toString());
1112:
1113: // Task Result Details
1114: TaskResultDetails compTaskResultDetails = getObjectFactory()
1115: .createTaskResultDetails();
1116:
1117: compTaskResultDetails
1118: .setTaskResultDetails(taskResultDetails);
1119: compRslt
1120: .setComponentTaskResultDetails(compTaskResultDetails);
1121: compResults.add(compRslt);
1122: }
1123:
1124: return compResults;
1125:
1126: }
1127:
1128: /**
1129: *
1130: */
1131: private ComponentInstanceResult[] extractMessageData(
1132: Map<String, JbiTask> jbiTasks,
1133: List<TaskStatusMsg> taskMsgs,
1134: List<ExceptionInfo> exceptions,
1135: ComponentInstanceResult[] compResultData)
1136: throws javax.xml.bind.JAXBException {
1137: Set<String> instances = jbiTasks.keySet();
1138:
1139: for (String instance : instances) {
1140: JbiTask jbiTask = jbiTasks.get(instance);
1141:
1142: List<TaskStatusMsg> instTaskMsgs = getTaskStatusMsgs(jbiTask);
1143: List<ExceptionInfo> instExceptions = getExceptionInfos(jbiTask);
1144:
1145: if (!instTaskMsgs.isEmpty()) {
1146: // -- Add the marker instance status message
1147: taskMsgs.add(buildTaskStatusMsg(instance,
1148: JBI_INSTANCE_NAME, new String[0]));
1149: }
1150:
1151: taskMsgs.addAll(instTaskMsgs);
1152:
1153: if (!instExceptions.isEmpty()) {
1154: // -- Add the marker instance exception info
1155: exceptions.add(buildExceptionInfo(instance,
1156: JBI_INSTANCE_NAME, new String[0]));
1157: }
1158:
1159: exceptions.addAll(instExceptions);
1160:
1161: List<ComponentTaskResult> compResults = jbiTask
1162: .getJbiTaskResult().getComponentTaskResult();
1163:
1164: int compOrder = 0;
1165: if (compResultData == null) {
1166: compResultData = new ComponentInstanceResult[compResults
1167: .size()];
1168: }
1169: for (ComponentTaskResult compResult : compResults) {
1170: String compName = compResult.getComponentName();
1171:
1172: if (compResultData[compOrder] == null) {
1173: HashMap<String, TaskResultDetails> instMap = new HashMap();
1174: compResultData[compOrder] = new ComponentInstanceResult(
1175: compName, new HashMap());
1176: }
1177:
1178: TaskResultDetailsElement taskDetails = ((TaskResultDetails) compResult
1179: .getComponentTaskResultDetails())
1180: .getTaskResultDetails();
1181:
1182: Map instMap = compResultData[compOrder]
1183: .getInstanceResults();
1184: instMap.put(instance, taskDetails);
1185: compOrder++;
1186: }
1187: }
1188: return compResultData;
1189: }
1190:
1191: /**
1192: *
1193: */
1194: private TaskResult getEffectiveTaskResult(
1195: List<TaskResult> taskResults, boolean requireAllSuccess) {
1196: TaskResult rslt = TaskResult.FAILED;
1197: if (requireAllSuccess) {
1198: if (taskResults.contains(TaskResult.FAILED)) {
1199: rslt = TaskResult.FAILED;
1200: } else {
1201: rslt = TaskResult.SUCCESS;
1202: }
1203: } else if (taskResults.contains(TaskResult.SUCCESS)) {
1204: rslt = TaskResult.SUCCESS;
1205: }
1206: return rslt;
1207: }
1208:
1209: /**
1210: * @param taskResults - task results based on which the message type is to be determined.
1211: * @param requireAllSuccess - if this is true, then even a single FAILED task result results
1212: * in a MessageType of ERROR. If false, then a single failed task
1213: * result implies a MessageType of WARNING.
1214: * @return the effective MessageType.
1215: */
1216: private MessageType getEffectiveMessageType(
1217: List<TaskResult> taskResults, boolean requireAllSuccess) {
1218: MessageType type = MessageType.INFO;
1219: if (requireAllSuccess) {
1220: if (taskResults.contains(TaskResult.FAILED)) {
1221: type = MessageType.ERROR;
1222: } else {
1223: type = MessageType.INFO;
1224: }
1225: } else if (taskResults.contains(TaskResult.FAILED)) {
1226: type = MessageType.WARNING;
1227: }
1228: return type;
1229: }
1230:
1231: /**
1232: *
1233: */
1234: private JbiTask appendComponentTaskResult(JbiTask jbiTask,
1235: List<ComponentTaskResult> compResults) {
1236: jbiTask.getJbiTaskResult().getComponentTaskResult().addAll(
1237: compResults);
1238:
1239: return jbiTask;
1240: }
1241:
1242: /**
1243: * Get the <task-result> from the framework task result message.
1244: */
1245: private TaskResult getTaskResult(JbiTask jbiTask) {
1246: TaskResult rslt = TaskResult.FAILED;
1247:
1248: TaskResultDetailsElement details = getTaskResultDetails(jbiTask);
1249:
1250: if (details != null) {
1251: String result = details.getTaskResult();
1252: rslt = TaskResult.valueOf(result);
1253: }
1254: return rslt;
1255: }
1256:
1257: /**
1258: * Get the <message-type> from the framework task result message.
1259: */
1260: private MessageType getMessageType(JbiTask jbiTask) {
1261: MessageType type = null;
1262:
1263: TaskResultDetailsElement details = getTaskResultDetails(jbiTask);
1264:
1265: if (details != null) {
1266: String msgType = details.getMessageType();
1267: if (msgType != null) {
1268: type = MessageType.valueOf(msgType);
1269: }
1270: }
1271: return type;
1272: }
1273:
1274: /**
1275: * @return the TaskResultDetails from the framework task result
1276: */
1277: private TaskResultDetailsElement getTaskResultDetails(
1278: JbiTask jbiTask) {
1279: TaskResultDetailsElement detailsType = null;
1280: JbiTaskResultElement jbiTaskRsltType = jbiTask
1281: .getJbiTaskResult();
1282:
1283: if (jbiTaskRsltType != null) {
1284: FrmwkTaskResult fmwkRslt = jbiTaskRsltType
1285: .getFrmwkTaskResult();
1286:
1287: if (fmwkRslt != null) {
1288: FrmwkTaskResultDetails details = fmwkRslt
1289: .getFrmwkTaskResultDetails();
1290:
1291: if (details != null) {
1292: detailsType = details.getTaskResultDetails();
1293: }
1294: }
1295: }
1296: return detailsType;
1297: }
1298:
1299: /**
1300: * Get the effective message type from the list of message types. The effective type
1301: * is the most severe type
1302: */
1303: private MessageType getEffectiveMessageType(
1304: List<MessageType> msgTypes) {
1305: MessageType msgType = null;
1306:
1307: if (!msgTypes.isEmpty()) {
1308: if (msgTypes.contains(MessageType.ERROR)) {
1309: msgType = MessageType.ERROR;
1310: } else if (msgTypes.contains(MessageType.WARNING)) {
1311: msgType = MessageType.WARNING;
1312: } else {
1313: msgType = MessageType.INFO;
1314: }
1315: }
1316: return msgType;
1317: }
1318:
1319: /** Provides a reference to the JAXB context for management messages,
1320: * initializing one if necessary.
1321: * @throws Excepion if the JAXB Context cannot be initialized
1322: */
1323: private synchronized JAXBContext getJaxbContext() throws Exception {
1324: if (mJaxbContext == null) {
1325: ClassLoader cl = Class.forName(
1326: "com.sun.jbi.management.message.JbiTaskResult")
1327: .getClassLoader();
1328: mJaxbContext = JAXBContext.newInstance(
1329: "com.sun.jbi.management.message", cl);
1330: }
1331:
1332: return mJaxbContext;
1333: }
1334:
1335: /** Synchronizes access to the non thread-safe Marshaller for this context.
1336: */
1337: private synchronized void marshal(Object jaxbElement,
1338: java.io.Writer writer) throws Exception {
1339: if (mWriter == null) {
1340: mWriter = getJaxbContext().createMarshaller();
1341: }
1342:
1343: mWriter.marshal(jaxbElement, writer);
1344: }
1345:
1346: /** Synchronizes access to the non thread-safe Unmarshaller for this context.
1347: */
1348: private synchronized Object unmarshal(StreamSource input)
1349: throws Exception {
1350: if (mReader == null) {
1351: mReader = getJaxbContext().createUnmarshaller();
1352: }
1353:
1354: return mReader.unmarshal(input);
1355: }
1356:
1357: }
|