001: /*
002: * $Id: InvalidRequestException.java,v 1.28 2007/05/15 11:33:15 agoubard Exp $
003: *
004: * Copyright 2003-2007 Orange Nederland Breedband B.V.
005: * See the COPYRIGHT file for redistribution and use restrictions.
006: */
007: package org.xins.client;
008:
009: import java.util.List;
010: import org.xins.common.service.TargetDescriptor;
011: import org.xins.common.text.TextUtils;
012: import org.xins.common.xml.Element;
013:
014: /**
015: * Exception thrown to indicate a standard error code was received that
016: * indicates the request from the client-side is considered invalid by the
017: * server-side.
018: *
019: * @version $Revision: 1.28 $ $Date: 2007/05/15 11:33:15 $
020: * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
021: *
022: * @since XINS 1.2.0
023: */
024: public class InvalidRequestException extends StandardErrorCodeException {
025:
026: /**
027: * Constructs a new <code>InvalidRequestException</code>.
028: *
029: * @param request
030: * the original request, guaranteed not to be <code>null</code>.
031: *
032: * @param target
033: * the target on which the request was executed, guaranteed not to be
034: * <code>null</code>.
035: *
036: * @param duration
037: * the call duration, guaranteed to be >= <code>0L</code>.
038: *
039: * @param resultData
040: * the data returned from the call, guaranteed to be <code>null</code>
041: * and must have an error code set.
042: *
043: * @throws IllegalArgumentException
044: * if <code>result == null
045: * || result.{@link XINSCallResultData#getErrorCode() getErrorCode()} == null</code>.
046: */
047: InvalidRequestException(XINSCallRequest request,
048: TargetDescriptor target, long duration,
049: XINSCallResultData resultData)
050: throws IllegalArgumentException {
051: super (request, target, duration, resultData,
052: determineDetail(resultData));
053: }
054:
055: /**
056: * Delegate for the constructor that determines the detail message based on
057: * a <code>XINSCallResultData</code> object.
058: *
059: * @param result
060: * the {@link XINSCallResultData} instance, should not be
061: * <code>null</code>.
062: *
063: * @return
064: * the detail message for the constructor to use, never
065: * <code>null</code>.
066: */
067: private static final String determineDetail(
068: XINSCallResultData result) {
069:
070: // Result must be unsuccessful
071: String errorCode = result.getErrorCode();
072: if (errorCode == null) {
073: throw new IllegalArgumentException(
074: "result.getErrorCode() == null");
075: }
076:
077: // Parse the data element
078: Element element = result.getDataElement();
079: return createMessage(element);
080: }
081:
082: /**
083: * Creates the message containing the details of the error.
084: *
085: * @param element
086: * the {@link Element} containing the details of the error, can be
087: * <code>null</code>.
088: *
089: * @return
090: * the message or <code>null</code> if <code>element == null</code>
091: * or empty.
092: */
093: static String createMessage(Element element) {
094:
095: // Parse the data element
096: if (element == null) {
097: return null;
098: }
099:
100: StringBuffer detail = new StringBuffer(250);
101:
102: // Handle all missing parameters
103: List missingParamElements = element
104: .getChildElements("missing-param");
105: if (missingParamElements != null) {
106: int size = missingParamElements.size();
107: for (int i = 0; i < size; i++) {
108: Element e = (Element) missingParamElements.get(i);
109: String paramName = e.getAttribute("param");
110: String elementName = e.getAttribute("element");
111: if (elementName == null && paramName != null
112: && paramName.length() >= 1) {
113: detail
114: .append("No value given for required parameter \""
115: + paramName + "\". ");
116: } else if (elementName != null
117: && elementName.length() >= 1
118: && paramName != null && paramName.length() >= 1) {
119: detail
120: .append("No value given for required attribute \""
121: + paramName
122: + "\" in the element \""
123: + elementName + "\". ");
124: }
125: }
126: }
127:
128: // Handle all invalid parameter values
129: List invalidValueElements = element
130: .getChildElements("invalid-value-for-type");
131: if (invalidValueElements != null) {
132: int size = invalidValueElements.size();
133: for (int i = 0; i < size; i++) {
134: Element e = (Element) invalidValueElements.get(i);
135: String paramName = e.getAttribute("param");
136: String invalidValue = e.getAttribute("value");
137: String typeName = e.getAttribute("type");
138: String elementName = e.getAttribute("element");
139: if (!TextUtils.isEmpty(elementName)
140: && !TextUtils.isEmpty(paramName)) {
141: detail.append("The value ");
142: if (invalidValue != null) {
143: detail.append("\"" + invalidValue + "\" ");
144: }
145: detail
146: .append("for the attribute \""
147: + paramName
148: + "\" in the element \""
149: + elementName
150: + "\" is considered invalid for the type \""
151: + typeName + "\". ");
152: } else if (!TextUtils.isEmpty(paramName)) {
153: detail.append("The value ");
154: if (invalidValue != null) {
155: detail.append("\"" + invalidValue + "\" ");
156: }
157: detail
158: .append("for the parameter \""
159: + paramName
160: + "\" is considered invalid for the type \""
161: + typeName + "\". ");
162: }
163: }
164: }
165:
166: // Handle all param-combo values
167: List paramComboElements = element
168: .getChildElements("param-combo");
169: if (paramComboElements != null) {
170: int size = paramComboElements.size();
171:
172: // Loop through all param-combo elements
173: for (int i = 0; i < size; i++) {
174: Element e = (Element) paramComboElements.get(i);
175:
176: // There should be a 'type' attribute
177: String typeName = e.getAttribute("type");
178: if (typeName == null || typeName.trim().length() < 1) {
179: // TODO: Log?
180: continue;
181: }
182:
183: // There should be at least 2 'param' elements
184: List paramList = e.getChildElements("param");
185: if (paramList == null || paramList.size() < 2) {
186: // TODO: Log?
187: continue;
188: }
189:
190: // Create detail message
191: detail
192: .append("Violated param-combo constraint of type \"");
193: detail.append(typeName);
194: detail.append("\" on parameters ");
195: int paramCount = paramList.size();
196: for (int j = 0; j < paramCount; j++) {
197: Element e2 = (Element) paramList.get(j);
198: String paramName = e2.getAttribute("name");
199: if (paramName == null
200: || paramName.trim().length() < 1) {
201: // TODO: Log?
202: continue;
203: }
204:
205: detail.append("\"");
206: detail.append(paramName);
207: detail.append("\"");
208:
209: if (j == (paramCount - 1)) {
210: detail.append(". ");
211: } else if (j == (paramCount - 2)) {
212: detail.append(" and ");
213: } else {
214: detail.append(", ");
215: }
216: }
217: }
218: }
219:
220: // Remove the last space from the string, if there is any
221: if (detail.length() >= 1) {
222: detail.deleteCharAt(detail.length() - 1);
223: return detail.toString();
224: } else {
225: return null;
226: }
227: }
228: }
|