KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > shipment > thirdparty > dhl > DhlServices


1 /*
2  *
3  * Copyright (c) 2003 The Open For Business Project - www.ofbiz.org
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
20  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */

23 package org.ofbiz.shipment.thirdparty.dhl;
24
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.StringWriter JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.LinkedList JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Locale JavaDoc;
34 import java.util.Map JavaDoc;
35
36 import javax.xml.parsers.ParserConfigurationException JavaDoc;
37
38 import org.ofbiz.base.util.Base64;
39 import org.ofbiz.base.util.Debug;
40 import org.ofbiz.base.util.GeneralException;
41 import org.ofbiz.base.util.HttpClient;
42 import org.ofbiz.base.util.HttpClientException;
43 import org.ofbiz.base.util.StringUtil;
44 import org.ofbiz.base.util.UtilDateTime;
45 import org.ofbiz.base.util.UtilMisc;
46 import org.ofbiz.base.util.UtilProperties;
47 import org.ofbiz.base.util.UtilValidate;
48 import org.ofbiz.base.util.UtilXml;
49 import org.ofbiz.service.ModelService;
50 import org.ofbiz.content.content.ContentWorker;
51 import org.ofbiz.entity.GenericDelegator;
52 import org.ofbiz.entity.GenericEntityException;
53 import org.ofbiz.entity.GenericValue;
54 import org.ofbiz.service.DispatchContext;
55 import org.ofbiz.service.LocalDispatcher;
56 import org.ofbiz.service.ServiceUtil;
57 import org.ofbiz.service.GenericServiceException;
58 import org.w3c.dom.Document JavaDoc;
59 import org.w3c.dom.Element JavaDoc;
60 import org.xml.sax.SAXException JavaDoc;
61
62 /**
63  * DHL ShipmentServices
64  *
65  * <p>Implementation of DHL US domestic shipment interface using DHL ShipIT XML APi.</p>
66  *
67  * Shipment services not supported in DHL ShipIT 1.1
68  * <ul>
69  * <li>Multiple Piece shipping (Shipment must not have more than one
70  * ShipmentPackage)</li>
71  * <li>Dynamic editing of previously submitted shipment (void first then
72  * resubmit instead)</li>
73  * <li>Label size 4"x6"</li>
74  * <li>Out of origin shipping</li>
75  * </ul>
76  *
77  * TODO: International
78  *
79  * @author <a HREF="mailto:leon@opensourcestrategies.com">Leon Torres </a>
80  * @author <a HREF="mailto:sichen@hotmail.com">Si Chen </a>
81  * @author <a HREF="mailto:timchen_sh@hotmail.com">Tim Chen </a>
82  */

83 public class DhlServices {
84
85     public final static String JavaDoc module = DhlServices.class.getName();
86     public final static String JavaDoc shipmentPropertiesFile = "shipment.properties";
87     public final static String JavaDoc DHL_WEIGHT_UOM_ID = "WT_lb"; // weight Uom used by DHL
88

89     /**
90      * Opens a URL to DHL and makes a request.
91      *
92      * @param dhlService
93      * Name of the DHL service to invoke
94      * @param xmlString
95      * XML message to send
96      * @return XML string response from DHL
97      * @throws DhlConnectException
98      */

99     public static String JavaDoc sendDhlRequest(String JavaDoc xmlString)
100             throws DhlConnectException {
101         String JavaDoc conStr = UtilProperties.getPropertyValue(shipmentPropertiesFile,
102                 "shipment.dhl.connect.url");
103         if (conStr == null) {
104             throw new DhlConnectException(
105                     "Incomplete connection URL; check your DHL configuration");
106         }
107
108         // xmlString should contain the auth document at the beginning
109
// all documents require an <?xml version="1.0"?> header
110
if (xmlString == null) {
111             throw new DhlConnectException("XML message cannot be null");
112         }
113
114         // prepare the connect string
115
conStr = conStr.trim();
116
117         String JavaDoc timeOutStr = UtilProperties.getPropertyValue(
118                 shipmentPropertiesFile, "shipment.dhl.connect.timeout", "60");
119         int timeout = 60;
120         try {
121             timeout = Integer.parseInt(timeOutStr);
122         } catch (NumberFormatException JavaDoc e) {
123             Debug.logError(e, "Unable to set timeout to " + timeOutStr
124                     + " using default " + timeout);
125         }
126
127         if (Debug.verboseOn()) {
128             Debug.logVerbose("DHL Connect URL : " + conStr, module);
129             Debug.logVerbose("DHL XML String : " + xmlString, module);
130         }
131
132         HttpClient http = new HttpClient(conStr);
133         http.setTimeout(timeout * 1000);
134         String JavaDoc response = null;
135         try {
136             response = http.post(xmlString);
137         } catch (HttpClientException e) {
138             Debug.logError(e, "Problem connecting with DHL server", module);
139             throw new DhlConnectException("URL Connection problem", e);
140         }
141
142         if (response == null) {
143             throw new DhlConnectException("Received a null response");
144         }
145         if (Debug.verboseOn()) {
146             Debug.logVerbose("DHL Response : " + response, module);
147         }
148
149         return response;
150     }
151
152
153     /*
154      * Service to obtain a rate estimate from DHL for a shipment. Notes: Only one package per shipment currently supported by DHL ShipIT.
155      * If this service returns a null shippingEstimateAmount, then the shipment has not been processed
156      */

157     public static Map JavaDoc dhlRateEstimate(DispatchContext dctx, Map JavaDoc context) {
158         GenericDelegator delegator = dctx.getDelegator();
159         LocalDispatcher dispatcher = dctx.getDispatcher();
160         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
161
162         // some of these can be refactored
163
String JavaDoc upsRateInquireMode = (String JavaDoc) context.get("upsRateInquireMode");
164         String JavaDoc carrierRoleTypeId = (String JavaDoc) context.get("carrierRoleTypeId");
165         String JavaDoc carrierPartyId = (String JavaDoc) context.get("carrierPartyId");
166         String JavaDoc shipmentMethodTypeId = (String JavaDoc) context.get("shipmentMethodTypeId");
167         String JavaDoc shippingContactMechId = (String JavaDoc) context.get("shippingContactMechId");
168         List JavaDoc shippableItemInfo = (List JavaDoc) context.get("shippableItemInfo");
169         Double JavaDoc shippableTotal = (Double JavaDoc) context.get("shippableTotal");
170         Double JavaDoc shippableQuantity = (Double JavaDoc) context.get("shippableQuantity");
171         Double JavaDoc shippableWeight = (Double JavaDoc) context.get("shippableWeight");
172         
173         if (shipmentMethodTypeId.equals("NO_SHIPPING")) {
174             Map JavaDoc result = ServiceUtil.returnSuccess();
175             result.put("shippingEstimateAmount", null);
176             return result;
177         }
178
179         // translate shipmentMethodTypeId to DHL service code
180
String JavaDoc dhlShipmentDetailCode = null;
181         try {
182             GenericValue carrierShipmentMethod = delegator.findByPrimaryKey("CarrierShipmentMethod", UtilMisc.toMap("shipmentMethodTypeId", shipmentMethodTypeId,
183                     "partyId", carrierPartyId, "roleTypeId", "CARRIER"));
184             if (carrierShipmentMethod == null) {
185                 return ServiceUtil.returnError("No CarrierShipmentMethod entry for carrier " + carrierPartyId + ", shipmentMethodTypeId " + shipmentMethodTypeId);
186             }
187             dhlShipmentDetailCode = carrierShipmentMethod.getString("carrierServiceCode");
188         } catch (GenericEntityException e) {
189             Debug.logError(e, "Failed to get rate estimate: " + e.getMessage(), module);
190         }
191
192         // shipping credentials (configured in properties)
193
String JavaDoc userid = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.dhl.access.userid");
194         String JavaDoc password = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.dhl.access.password");
195         String JavaDoc shippingKey = UtilProperties.getPropertyValue("shipment", "shipment.dhl.access.shippingKey");
196         String JavaDoc accountNbr = UtilProperties.getPropertyValue("shipment", "shipment.dhl.access.accountNbr");
197         if ((shippingKey == null) || (accountNbr == null) || (shippingKey.length() == 0) || (accountNbr.length() == 0)) {
198             return ServiceUtil.returnError("DHL Shipping Credentials are not configured. (check shipment.dhl.access)");
199         }
200
201         // obtain the ship-to address
202
GenericValue shipToAddress = null;
203         if (shippingContactMechId != null) {
204             try {
205                 shipToAddress = delegator.findByPrimaryKey("PostalAddress", UtilMisc.toMap("contactMechId", shippingContactMechId));
206                 if (shipToAddress == null) {
207                     return ServiceUtil.returnError("Unable to determine ship-to address");
208                 }
209             }
210             catch (GenericEntityException e) {
211                 Debug.logError(e, module);
212             }
213         }
214
215         if ((shippableWeight == null) || (shippableWeight.doubleValue() <= 0.0)) {
216             String JavaDoc tmpValue = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.default.weight.value");
217             if (tmpValue != null) {
218                 try {
219                     shippableWeight = new Double JavaDoc(tmpValue);
220                 } catch (Exception JavaDoc e) {
221                     return ServiceUtil.returnError("Cannot get DHL Estimate: Default shippable weight not configured (shipment.default.weight.value)");
222                 }
223             }
224         }
225
226         // TODO: if a weight UOM is passed in, use convertUom service to convert it here
227
if (shippableWeight.doubleValue() < 1.0) {
228             Debug.logWarning("DHL Estimate: Weight is less than 1 lb, submitting DHL minimum of 1 lb for estimate.", module);
229             shippableWeight = new Double JavaDoc(1.0);
230         }
231         if ((dhlShipmentDetailCode.equals("G") && shippableWeight.doubleValue() > 999) || (shippableWeight.doubleValue() > 150)) {
232             return ServiceUtil.returnError("Cannot get DHL Estimate: Shippable weight cannot be greater than 999 lbs for ground or 150 lbs for all other services.");
233         }
234         String JavaDoc weight = (new Integer JavaDoc((int) shippableWeight.longValue())).toString();
235
236         // create AccessRequest XML doc using FreeMarker template
237
String JavaDoc templateName = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.template.dhl.rate.estimate");
238         if ((templateName == null) || (templateName.trim().length() == 0)) {
239             return ServiceUtil.returnError("Cannot get DHL Estimate: DHL Rate template not configured (shipment.template.dhl.rate.estimate");
240         }
241         StringWriter JavaDoc outWriter = new StringWriter JavaDoc();
242         Map JavaDoc inContext = new HashMap JavaDoc();
243         inContext.put("action", "RateEstimate");
244         inContext.put("userid", userid);
245         inContext.put("password", password);
246         inContext.put("accountNbr", accountNbr);
247         inContext.put("shippingKey", shippingKey);
248         inContext.put("shipDate", UtilDateTime.nowTimestamp());
249         inContext.put("dhlShipmentDetailCode", dhlShipmentDetailCode);
250         inContext.put("weight", weight);
251         inContext.put("state", shipToAddress.getString("stateProvinceGeoId"));
252         inContext.put("postalCode", shipToAddress.getString("postalCode"));
253         try {
254             Map JavaDoc tmpResult = ContentWorker.renderContentAsText(delegator, templateName, outWriter, inContext, null, locale, "text/plain");
255         } catch (Exception JavaDoc e) {
256             Debug.logError(e, "Cannot get DHL Estimate: Failed to render DHL XML Request.", module);
257             return ServiceUtil.returnError("Cannot get DHL Estimate: Failed to render DHL XML Request.");
258         }
259         String JavaDoc requestString = outWriter.toString();
260         if (Debug.verboseOn()) {
261             Debug.logVerbose(requestString, module);
262         }
263
264         // send the request
265
String JavaDoc rateResponseString = null;
266         try {
267             rateResponseString = sendDhlRequest(requestString);
268             if (Debug.verboseOn()) {
269                 Debug.logVerbose(rateResponseString, module);
270             }
271         }
272         catch (DhlConnectException e) {
273             String JavaDoc uceErrMsg = "Error sending DHL request for DHL Service Rate: " + e.toString();
274             Debug.logError(e, uceErrMsg, module);
275             return ServiceUtil.returnError(uceErrMsg);
276         }
277
278         Document JavaDoc rateResponseDocument = null;
279         try {
280             rateResponseDocument = UtilXml.readXmlDocument(rateResponseString, false);
281             return handleDhlRateResponse(rateResponseDocument);
282         }
283         catch (SAXException JavaDoc e2) {
284             String JavaDoc excErrMsg = "Error parsing the RatingServiceResponse: " + e2.toString();
285             Debug.logError(e2, excErrMsg, module);
286             return ServiceUtil.returnError(excErrMsg);
287         }
288         catch (ParserConfigurationException JavaDoc e2) {
289             String JavaDoc excErrMsg = "Error parsing the RatingServiceResponse: " + e2.toString();
290             Debug.logError(e2, excErrMsg, module);
291             return ServiceUtil.returnError(excErrMsg);
292         }
293         catch (IOException JavaDoc e2) {
294             String JavaDoc excErrMsg = "Error parsing the RatingServiceResponse: " + e2.toString();
295             Debug.logError(e2, excErrMsg, module);
296             return ServiceUtil.returnError(excErrMsg);
297         }
298     }
299
300     /*
301      * Parses an XML document from DHL to get the rate estimate
302      */

303     public static Map JavaDoc handleDhlRateResponse(Document JavaDoc rateResponseDocument) {
304         List JavaDoc errorList = new LinkedList JavaDoc();
305         Map JavaDoc dhlRateCodeMap = new HashMap JavaDoc();
306         // process RateResponse
307
Element JavaDoc rateResponseElement = rateResponseDocument.getDocumentElement();
308         DhlServices.handleErrors(rateResponseElement, errorList);
309         if (UtilValidate.isNotEmpty(errorList)) {
310             return ServiceUtil.returnError(errorList);
311         }
312         // handle Response element info
313
Element JavaDoc responseElement = UtilXml.firstChildElement(
314                 rateResponseElement, "Shipment");
315         Element JavaDoc responseResultElement = UtilXml.firstChildElement(
316                 responseElement, "Result");
317         Element JavaDoc responseEstimateDetailElement = UtilXml.firstChildElement(
318                 responseElement, "EstimateDetail");
319
320         DhlServices.handleErrors(responseElement, errorList);
321         if (UtilValidate.isNotEmpty(errorList)) {
322             return ServiceUtil.returnError(errorList);
323         }
324         String JavaDoc responseStatusCode = UtilXml.childElementValue(
325                 responseResultElement, "Code");
326         String JavaDoc responseStatusDescription = UtilXml.childElementValue(
327                 responseResultElement, "Desc");
328
329         String JavaDoc dateGenerated = UtilXml.childElementValue(
330                 responseEstimateDetailElement, "DateGenerated");
331
332         Element JavaDoc responseServiceLevelCommitmentElement = UtilXml
333             .firstChildElement(responseEstimateDetailElement,
334                     "ServiceLevelCommitment");
335         String JavaDoc responseServiceLevelCommitmentDescription = UtilXml
336             .childElementValue(responseServiceLevelCommitmentElement,
337                     "Desc");
338
339         Element JavaDoc responseRateEstimateElement = UtilXml.firstChildElement(
340                 responseEstimateDetailElement, "RateEstimate");
341         String JavaDoc responseTotalChargeEstimate = UtilXml.childElementValue(
342                 responseRateEstimateElement, "TotalChargeEstimate");
343         Element JavaDoc responseChargesElement = UtilXml.firstChildElement(
344                 responseRateEstimateElement, "Charges");
345         List JavaDoc chargeNodeList = UtilXml.childElementList(responseChargesElement,
346                 "Charge");
347
348         List JavaDoc chargeList = new ArrayList JavaDoc();
349         if (chargeNodeList != null && chargeNodeList.size() > 0) {
350             for (int i = 0; chargeNodeList.size() > i; i++) {
351                 Map JavaDoc charge = new HashMap JavaDoc();
352
353                 Element JavaDoc responseChargeElement = (Element JavaDoc) chargeNodeList.get(i);
354                 Element JavaDoc responseChargeTypeElement = UtilXml.firstChildElement(
355                         responseChargeElement, "Type");
356
357                 String JavaDoc responseChargeTypeCode = UtilXml.childElementValue(
358                         responseChargeTypeElement, "Code");
359                 String JavaDoc responseChargeTypeDesc = UtilXml.childElementValue(
360                         responseChargeTypeElement, "Desc");
361                 String JavaDoc responseChargeValue = UtilXml.childElementValue(
362                         responseChargeElement, "Value");
363
364                 charge.put("chargeTypeCode", responseChargeTypeCode);
365                 charge.put("chargeTypeDesc", responseChargeTypeDesc);
366                 charge.put("chargeValue", responseChargeValue);
367                 chargeList.add(charge);
368             }
369         }
370         Double JavaDoc shippingEstimateAmount = new Double JavaDoc(responseTotalChargeEstimate);
371         dhlRateCodeMap.put("dateGenerated", dateGenerated);
372         dhlRateCodeMap.put("serviceLevelCommitment",
373                 responseServiceLevelCommitmentDescription);
374         dhlRateCodeMap.put("totalChargeEstimate", responseTotalChargeEstimate);
375         dhlRateCodeMap.put("chargeList", chargeList);
376
377         Map JavaDoc result = ServiceUtil.returnSuccess();
378         result.put("shippingEstimateAmount", shippingEstimateAmount);
379         result.put("dhlRateCodeMap", dhlRateCodeMap);
380         return result;
381     }
382
383     /*
384      * Register a DHL account for shipping by obtaining the DHL shipping key
385      */

386     public static Map JavaDoc dhlRegisterInquire(DispatchContext dctx, Map JavaDoc context) {
387
388         Map JavaDoc result = new HashMap JavaDoc();
389         String JavaDoc postalCode = (String JavaDoc) context.get("postalCode");
390         String JavaDoc accountNbr = UtilProperties.getPropertyValue("shipment",
391                 "shipment.dhl.access.accountNbr");
392         if (accountNbr == null) {
393             return ServiceUtil
394                 .returnError("accountNbr not found for Register Account.");
395         }
396         // create AccessRequest XML doc
397
Document JavaDoc requestDocument = createAccessRequestDocument();
398         String JavaDoc requestString = null;
399         Element JavaDoc requesElement = requestDocument.getDocumentElement();
400
401         Element JavaDoc registerRequestElement = UtilXml.addChildElement(requesElement,
402                 "Register", requestDocument);
403         registerRequestElement.setAttribute("version", "1.0");
404         registerRequestElement.setAttribute("action", "ShippingKey");
405         UtilXml.addChildElementValue(registerRequestElement, "AccountNbr",
406                 accountNbr, requestDocument);
407         UtilXml.addChildElementValue(registerRequestElement, "PostalCode",
408                 postalCode, requestDocument);
409
410         try {
411             requestString = UtilXml.writeXmlDocument(requestDocument);
412             Debug.log("AccessRequest XML Document:" + requestString);
413         } catch (IOException JavaDoc e) {
414             String JavaDoc ioeErrMsg = "Error writing the AccessRequest XML Document to a String: "
415                 + e.toString();
416             Debug.logError(e, ioeErrMsg, module);
417             return ServiceUtil.returnError(ioeErrMsg);
418         }
419         // send the request
420
String JavaDoc registerResponseString = null;
421         try {
422             registerResponseString = sendDhlRequest(requestString);
423             Debug.log("DHL request for DHL Register Account:"
424                     + registerResponseString);
425         } catch (DhlConnectException e) {
426             String JavaDoc uceErrMsg = "Error sending DHL request for DHL Register Account: "
427                 + e.toString();
428             Debug.logError(e, uceErrMsg, module);
429             return ServiceUtil.returnError(uceErrMsg);
430         }
431
432         Document JavaDoc registerResponseDocument = null;
433         try {
434             registerResponseDocument = UtilXml.readXmlDocument(
435                     registerResponseString, false);
436             result = handleDhlRegisterResponse(registerResponseDocument);
437             Debug.log("DHL response for DHL Register Account:"
438                     + registerResponseString);
439         } catch (SAXException JavaDoc e2) {
440             String JavaDoc excErrMsg = "Error parsing the RegisterAccountServiceSelectionResponse: "
441                 + e2.toString();
442             Debug.logError(e2, excErrMsg, module);
443             return ServiceUtil.returnError(excErrMsg);
444         } catch (ParserConfigurationException JavaDoc e2) {
445             String JavaDoc excErrMsg = "Error parsing the RegisterAccountServiceSelectionResponse: "
446                 + e2.toString();
447             Debug.logError(e2, excErrMsg, module);
448             return ServiceUtil.returnError(excErrMsg);
449         } catch (IOException JavaDoc e2) {
450             String JavaDoc excErrMsg = "Error parsing the RegisterAccountServiceSelectionResponse: "
451                 + e2.toString();
452             Debug.logError(e2, excErrMsg, module);
453             return ServiceUtil.returnError(excErrMsg);
454         }
455
456         return result;
457     }
458
459     /*
460      * Parse response from DHL registration request to get shipping key
461      */

462     public static Map JavaDoc handleDhlRegisterResponse(
463             Document JavaDoc registerResponseDocument) {
464         List JavaDoc errorList = new LinkedList JavaDoc();
465         // process RegisterResponse
466
Element JavaDoc registerResponseElement = registerResponseDocument
467             .getDocumentElement();
468         DhlServices.handleErrors(registerResponseElement, errorList);
469         if (UtilValidate.isNotEmpty(errorList)) {
470             return ServiceUtil.returnError(errorList);
471         }
472         // handle Response element info
473
Element JavaDoc responseElement = UtilXml.firstChildElement(
474                 registerResponseElement, "Register");
475         Element JavaDoc responseResultElement = UtilXml.firstChildElement(
476                 responseElement, "Result");
477
478         DhlServices.handleErrors(responseElement, errorList);
479         if (UtilValidate.isNotEmpty(errorList)) {
480             return ServiceUtil.returnError(errorList);
481         }
482         String JavaDoc responseStatusCode = UtilXml.childElementValue(
483                 responseResultElement, "Code");
484         String JavaDoc responseStatusDescription = UtilXml.childElementValue(
485                 responseResultElement, "Desc");
486
487         String JavaDoc responseShippingKey = UtilXml.childElementValue(responseElement,
488                 "ShippingKey");
489         String JavaDoc responsePostalCode = UtilXml.childElementValue(responseElement,
490                 "PostalCode");
491
492         Map JavaDoc result = ServiceUtil.returnSuccess();
493         result.put("shippingKey", responseShippingKey);
494         return result;
495     }
496
497     /*
498      * Pass a shipment request to DHL via ShipIT and get a tracking number and a label back, among other things
499      */

500
501     public static Map JavaDoc dhlShipmentConfirm(DispatchContext dctx, Map JavaDoc context) {
502         GenericDelegator delegator = dctx.getDelegator();
503         LocalDispatcher dispatcher = dctx.getDispatcher();
504         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
505         
506         String JavaDoc shipmentId = (String JavaDoc) context.get("shipmentId");
507         String JavaDoc shipmentRouteSegmentId = (String JavaDoc) context.get("shipmentRouteSegmentId");
508         Map JavaDoc result = new HashMap JavaDoc();
509         String JavaDoc shipmentConfirmResponseString = null;
510         try {
511             GenericValue shipment = delegator.findByPrimaryKey("Shipment", UtilMisc.toMap("shipmentId", shipmentId));
512             if (shipment == null) {
513                 return ServiceUtil.returnError("Shipment not found with ID " + shipmentId);
514             }
515             GenericValue shipmentRouteSegment = delegator.findByPrimaryKey("ShipmentRouteSegment", UtilMisc.toMap("shipmentId", shipmentId, "shipmentRouteSegmentId", shipmentRouteSegmentId));
516             if (shipmentRouteSegment == null) {
517                 return ServiceUtil.returnError("ShipmentRouteSegment not found with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
518             }
519             
520             if (!"DHL".equals(shipmentRouteSegment.getString("carrierPartyId"))) {
521                 return ServiceUtil.returnError("ERROR: The Carrier for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is not DHL.");
522             }
523             
524             // add ShipmentRouteSegment carrierServiceStatusId, check before all DHL services
525
if (UtilValidate.isNotEmpty(shipmentRouteSegment.getString("carrierServiceStatusId")) && !"SHRSCS_NOT_STARTED".equals(shipmentRouteSegment.getString("carrierServiceStatusId"))) {
526                 return ServiceUtil.returnError("ERROR: The Carrier Service Status for ShipmentRouteSegment " + shipmentRouteSegmentId + " of Shipment " + shipmentId + ", is [" + shipmentRouteSegment.getString("carrierServiceStatusId") + "], but must be not-set or [SHRSCS_NOT_STARTED] to perform the DHL Shipment Confirm operation.");
527             }
528             
529             // Get Origin Info
530
GenericValue originPostalAddress = shipmentRouteSegment.getRelatedOne("OriginPostalAddress");
531             if (originPostalAddress == null) {
532                 return ServiceUtil.returnError("OriginPostalAddress not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
533             }
534             GenericValue originTelecomNumber = shipmentRouteSegment.getRelatedOne("OriginTelecomNumber");
535             if (originTelecomNumber == null) {
536                 return ServiceUtil.returnError("OriginTelecomNumber not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
537             }
538             String JavaDoc originPhoneNumber = originTelecomNumber.getString("areaCode") + originTelecomNumber.getString("contactNumber");
539             // don't put on country code if not specified or is the US country code (UPS wants it this way and assuming DHL will accept this)
540
if (UtilValidate.isNotEmpty(originTelecomNumber.getString("countryCode")) && !"001".equals(originTelecomNumber.getString("countryCode"))) {
541                 originPhoneNumber = originTelecomNumber.getString("countryCode") + originPhoneNumber;
542             }
543             originPhoneNumber = StringUtil.replaceString(originPhoneNumber, "-", "");
544             originPhoneNumber = StringUtil.replaceString(originPhoneNumber, " ", "");
545             
546             // lookup the two letter country code (in the geoCode field)
547
GenericValue originCountryGeo = originPostalAddress.getRelatedOne("CountryGeo");
548             if (originCountryGeo == null) {
549                 return ServiceUtil.returnError("OriginCountryGeo not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
550             }
551
552             // Get Dest Info
553
GenericValue destPostalAddress = shipmentRouteSegment.getRelatedOne("DestPostalAddress");
554             if (destPostalAddress == null) {
555                 return ServiceUtil.returnError("DestPostalAddress not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
556             }
557
558             // DHL requires destination phone number, default to sender # if no customer number
559
String JavaDoc destPhoneNumber = originPhoneNumber;
560             GenericValue destTelecomNumber = shipmentRouteSegment.getRelatedOne("DestTelecomNumber");
561             if (destTelecomNumber != null) {
562                 destPhoneNumber = destTelecomNumber.getString("areaCode") + destTelecomNumber.getString("contactNumber");
563                 // don't put on country code if not specified or is the US country code (UPS wants it this way)
564
if (UtilValidate.isNotEmpty(destTelecomNumber.getString("countryCode")) && !"001".equals(destTelecomNumber.getString("countryCode"))) {
565                     destPhoneNumber = destTelecomNumber.getString("countryCode") + destPhoneNumber;
566                 }
567                 destPhoneNumber = StringUtil.replaceString(destPhoneNumber, "-", "");
568                 destPhoneNumber = StringUtil.replaceString(destPhoneNumber, " ", "");
569             }
570
571             // lookup the two letter country code (in the geoCode field)
572
GenericValue destCountryGeo = destPostalAddress.getRelatedOne("CountryGeo");
573             if (destCountryGeo == null) {
574                 return ServiceUtil.returnError("DestCountryGeo not found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
575             }
576
577             List JavaDoc shipmentPackageRouteSegs = shipmentRouteSegment.getRelated("ShipmentPackageRouteSeg", null, UtilMisc.toList("+shipmentPackageSeqId"));
578             if (shipmentPackageRouteSegs == null || shipmentPackageRouteSegs.size() == 0) {
579                 return ServiceUtil.returnError("No ShipmentPackageRouteSegs (ie No Packages) found for ShipmentRouteSegment with shipmentId " + shipmentId + " and shipmentRouteSegmentId " + shipmentRouteSegmentId);
580             }
581             if (shipmentPackageRouteSegs.size() != 1) {
582                return ServiceUtil.returnError("Cannot confirm shipment: DHL ShipIT does not currently support more than one package per shipment.");
583             }
584
585             // get the weight from the ShipmentRouteSegment first, which overrides all later weight computations
586
boolean hasBillingWeight = false; // for later overrides
587
Double JavaDoc billingWeight = shipmentRouteSegment.getDouble("billingWeight");
588             String JavaDoc billingWeightUomId = shipmentRouteSegment.getString("billingWeightUomId");
589             if ((billingWeight != null) && (billingWeight.doubleValue() > 0)) {
590                 hasBillingWeight = true;
591                 if (billingWeightUomId == null) {
592                     Debug.logWarning("Shipment Route Segment missing billingWeightUomId in shipmentId " + shipmentId, module);
593                     billingWeightUomId = "WT_lb"; // TODO: this should be specified in a properties file
594
}
595                 // convert
596
Map JavaDoc results = dispatcher.runSync("convertUom", UtilMisc.toMap("uomId", billingWeightUomId, "uomIdTo", DHL_WEIGHT_UOM_ID, "originalValue", billingWeight));
597                 if (ServiceUtil.isError(results) || (results.get("convertedValue") == null)) {
598                     Debug.logWarning("Unable to convert billing weights for shipmentId " + shipmentId , module);
599                     // try getting the weight from package instead
600
hasBillingWeight = false;
601                 } else {
602                     billingWeight = (Double JavaDoc) results.get("convertedValue");
603                 }
604             }
605
606             // loop through Shipment segments (NOTE: only one supported, loop is here for future refactoring reference)
607
String JavaDoc length = null;
608             String JavaDoc width = null;
609             String JavaDoc height = null;
610             Double JavaDoc packageWeight = null;
611             Iterator JavaDoc shipmentPackageRouteSegIter = shipmentPackageRouteSegs.iterator();
612             while (shipmentPackageRouteSegIter.hasNext()) {
613                 GenericValue shipmentPackageRouteSeg = (GenericValue) shipmentPackageRouteSegIter.next();
614                 GenericValue shipmentPackage = shipmentPackageRouteSeg.getRelatedOne("ShipmentPackage");
615                 GenericValue shipmentBoxType = shipmentPackage.getRelatedOne("ShipmentBoxType");
616                 List JavaDoc carrierShipmentBoxTypes = shipmentPackage.getRelated("CarrierShipmentBoxType", UtilMisc.toMap("partyId", "DHL"), null);
617                 GenericValue carrierShipmentBoxType = null;
618                 if (carrierShipmentBoxTypes.size() > 0) {
619                     carrierShipmentBoxType = (GenericValue) carrierShipmentBoxTypes.get(0);
620                 }
621                  
622                 // TODO: determine what default UoM is (assuming inches) - there should be a defaultDimensionUomId in Facility
623
if (shipmentBoxType != null) {
624                     GenericValue dimensionUom = shipmentBoxType.getRelatedOne("DimensionUom");
625                     length = shipmentBoxType.get("boxLength").toString();
626                     width = shipmentBoxType.get("boxWidth").toString();
627                     height = shipmentBoxType.get("boxHeight").toString();
628                 }
629                 
630                 // next step is weight determination, so skip if we have a billing weight
631
if (hasBillingWeight) continue;
632
633                 // compute total packageWeight (for now, just one package)
634
if (shipmentPackage.getString("weight") != null) {
635                     packageWeight = Double.valueOf(shipmentPackage.getString("weight"));
636                 } else {
637                     // use default weight if available
638
try {
639                         packageWeight = Double.valueOf(UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.default.weight.value"));
640                     } catch (NumberFormatException JavaDoc ne) {
641                         Debug.logWarning("Default shippable weight not configured (shipment.default.weight.value)", module);
642                         packageWeight = new Double JavaDoc(1.0);
643                     }
644                 }
645                 // convert weight
646
String JavaDoc weightUomId = (String JavaDoc) shipmentPackage.get("weightUomId");
647                 if (weightUomId == null) {
648                     Debug.logWarning("Shipment Route Segment missing weightUomId in shipmentId " + shipmentId, module);
649                     weightUomId = "WT_lb"; // TODO: this should be specified in a properties file
650
}
651                 Map JavaDoc results = dispatcher.runSync("convertUom", UtilMisc.toMap("uomId", weightUomId, "uomIdTo", DHL_WEIGHT_UOM_ID, "originalValue", packageWeight));
652                 if ((results == null) || (results.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_ERROR)) || (results.get("convertedValue") == null)) {
653                     Debug.logWarning("Unable to convert weights for shipmentId " + shipmentId , module);
654                     packageWeight = new Double JavaDoc(1.0);
655                 } else {
656                     packageWeight = (Double JavaDoc) results.get("convertedValue");
657                 }
658             }
659
660             // pick which weight to use and round it
661
Double JavaDoc weight = null;
662             if (hasBillingWeight) {
663                 weight = billingWeight;
664             } else {
665                 weight = packageWeight;
666             }
667             // want the rounded weight as a string, so we use the "" + int shortcut
668
String JavaDoc roundedWeight = "" + Math.round(weight.doubleValue());
669             
670             // translate shipmentMethodTypeId to DHL service code
671
String JavaDoc shipmentMethodTypeId = shipmentRouteSegment.getString("shipmentMethodTypeId");
672             String JavaDoc dhlShipmentDetailCode = null;
673             GenericValue carrierShipmentMethod = delegator.findByPrimaryKey("CarrierShipmentMethod", UtilMisc.toMap("shipmentMethodTypeId", shipmentMethodTypeId,
674                     "partyId", "DHL", "roleTypeId", "CARRIER"));
675             if (carrierShipmentMethod == null) {
676                 return ServiceUtil.returnError("No CarrierShipmentMethod entry for carrier DHL shipmentMethodTypeId " + shipmentMethodTypeId);
677             }
678             dhlShipmentDetailCode = carrierShipmentMethod.getString("carrierServiceCode");
679
680             // shipping credentials (configured in properties)
681
String JavaDoc userid = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.dhl.access.userid");
682             String JavaDoc password = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.dhl.access.password");
683             String JavaDoc shippingKey = UtilProperties.getPropertyValue("shipment", "shipment.dhl.access.shippingKey");
684             String JavaDoc accountNbr = UtilProperties.getPropertyValue("shipment", "shipment.dhl.access.accountNbr");
685             if ((shippingKey == null) || (accountNbr == null) || (shippingKey.length() == 0) || (accountNbr.length() == 0)) {
686                 return ServiceUtil.returnError("DHL Shipping Credentials are not configured. (check shipment.dhl.access)");
687             }
688             
689             // label image preference (PNG or GIF)
690
String JavaDoc labelImagePreference = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.dhl.label.image.format");
691             if (labelImagePreference == null) {
692                 Debug.logInfo("shipment.dhl.label.image.format not specified, assuming PNG", module);
693                 labelImagePreference="PNG";
694             } else if (!(labelImagePreference.equals("PNG") || labelImagePreference.equals("GIF"))) {
695                 Debug.logError("Illegal shipment.dhl.label.image.format: " + labelImagePreference, module);
696                 return ServiceUtil.returnError("Unknown DHL Label Image Format: " + labelImagePreference);
697             }
698             
699             // create AccessRequest XML doc using FreeMarker template
700
String JavaDoc templateName = UtilProperties.getPropertyValue(shipmentPropertiesFile, "shipment.template.dhl.rate.estimate");
701             if ((templateName == null) || (templateName.trim().length() == 0)) {
702                 return ServiceUtil.returnError("Cannot get DHL Estimate: DHL Rate template not configured (shipment.template.dhl.rate.estimate");
703             }
704             StringWriter JavaDoc outWriter = new StringWriter JavaDoc();
705             Map JavaDoc inContext = new HashMap JavaDoc();
706             inContext.put("action", "GenerateLabel");
707             inContext.put("userid", userid);
708             inContext.put("password", password);
709             inContext.put("accountNbr", accountNbr);
710             inContext.put("shippingKey", shippingKey);
711             inContext.put("shipDate", UtilDateTime.nowTimestamp());
712             inContext.put("dhlShipmentDetailCode", dhlShipmentDetailCode);
713             inContext.put("weight", roundedWeight);
714             inContext.put("senderPhoneNbr", originPhoneNumber);
715             inContext.put("companyName", destPostalAddress.getString("toName"));
716             inContext.put("attnTo", destPostalAddress.getString("attnName"));
717             inContext.put("street", destPostalAddress.getString("address1"));
718             inContext.put("streetLine2", destPostalAddress.getString("address2"));
719             inContext.put("city", destPostalAddress.getString("city"));
720             inContext.put("state", destPostalAddress.getString("stateProvinceGeoId"));
721             inContext.put("postalCode", destPostalAddress.getString("postalCode"));
722             inContext.put("phoneNbr", destPhoneNumber);
723             inContext.put("labelImageType", labelImagePreference);
724             
725             try {
726                 Map JavaDoc tmpResult = ContentWorker.renderContentAsText(delegator, templateName, outWriter, inContext, null, locale, "text/plain");
727             } catch (Exception JavaDoc e) {
728                 Debug.logError(e, "Cannot confirm DHL shipment: Failed to render DHL XML Request.", module);
729                 return ServiceUtil.returnError("Cannot confirm DHL shipment: Failed to render DHL XML Request.");
730             }
731             String JavaDoc requestString = outWriter.toString();
732             if (Debug.verboseOn()) {
733                 Debug.logVerbose(requestString, module);
734             }
735
736             // send the request
737
String JavaDoc responseString = null;
738             try {
739                 responseString = sendDhlRequest(requestString);
740                 if (Debug.verboseOn()) {
741                     Debug.logVerbose(responseString, module);
742                 }
743             } catch (DhlConnectException e) {
744                 String JavaDoc uceErrMsg = "Error sending DHL request for DHL Service Rate: " + e.toString();
745                 Debug.logError(e, uceErrMsg, module);
746                 return ServiceUtil.returnError(uceErrMsg);
747             }
748             // pass to handler method
749
return handleDhlShipmentConfirmResponse(responseString, shipmentRouteSegment, shipmentPackageRouteSegs);
750             
751         } catch (GenericEntityException e) {
752             Debug.logError(e, module);
753             if (shipmentConfirmResponseString != null) {
754                 Debug.logError("Got XML ShipmentConfirmRespose: " + shipmentConfirmResponseString, module);
755                 return ServiceUtil.returnError(UtilMisc.toList(
756                             "Error reading or writing Shipment data for DHL Shipment Confirm: " + e.toString(),
757                             "A ShipmentConfirmRespose was received: " + shipmentConfirmResponseString));
758             } else {
759                 return ServiceUtil.returnError("Error reading or writing Shipment data for DHL Shipment Confirm: " + e.toString());
760             }
761         } catch (GenericServiceException e) {
762             Debug.logError(e, module);
763             return ServiceUtil.returnError("Error reading or writing Shipment data for DHL Shipment Confirm: " + e.toString());
764         }
765     }
766
767     // NOTE: Must VOID shipments on errors
768
public static Map JavaDoc handleDhlShipmentConfirmResponse(String JavaDoc rateResponseString, GenericValue shipmentRouteSegment,
769             List JavaDoc shipmentPackageRouteSegs) throws GenericEntityException {
770         Map JavaDoc result = new HashMap JavaDoc();
771         GenericValue shipmentPackageRouteSeg = (GenericValue) shipmentPackageRouteSegs.get(0);
772         
773         // TODO: figure out how to handle validation on return XML, which can be mangled
774
// Ideas: try again right away, let user try again, etc.
775
Document JavaDoc rateResponseDocument = null;
776         try {
777             rateResponseDocument = UtilXml.readXmlDocument(rateResponseString, false);
778         } catch (SAXException JavaDoc e2) {
779             String JavaDoc excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString();
780             Debug.logError(e2, excErrMsg, module);
781             // TODO: VOID
782
} catch (ParserConfigurationException JavaDoc e2) {
783             String JavaDoc excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString();
784             Debug.logError(e2, excErrMsg, module);
785             // TODO VOID
786
} catch (IOException JavaDoc e2) {
787             String JavaDoc excErrMsg = "Error parsing the RatingServiceSelectionResponse: " + e2.toString();
788             Debug.logError(e2, excErrMsg, module);
789             // TODO VOID
790
}
791         
792         // tracking number: Shipment/ShipmentDetail/AirbillNbr
793
Element JavaDoc rootElement = rateResponseDocument.getDocumentElement();
794         Element JavaDoc shipmentElement = UtilXml.firstChildElement(rootElement, "Shipment");
795         Element JavaDoc shipmentDetailElement = UtilXml.firstChildElement(shipmentElement, "ShipmentDetail");
796         String JavaDoc trackingNumber = UtilXml.childElementValue(shipmentDetailElement, "AirbillNbr");
797         
798         // label: Shipment/Label/Image
799
Element JavaDoc labelElement = UtilXml.firstChildElement(shipmentElement, "Label");
800         String JavaDoc encodedImageString = UtilXml.childElementValue(labelElement, "Image");
801         if (encodedImageString == null) {
802             Debug.logError("Cannot find response DHL shipment label. Rate response document is: " + rateResponseString, module);
803             return ServiceUtil.returnError("Cannot get response DHL shipment label for shipment package route segment " + shipmentPackageRouteSeg + ". DHL response is: " + rateResponseString);
804         }
805         
806         // TODO: this is a temporary hack to replace the newlines so that Base64 likes the input This is NOT platform independent
807
int size = encodedImageString.length();
808         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
809         for (int i = 0; i < size; i++) {
810             if (encodedImageString.charAt(i) == '\n')
811                 continue;
812             sb.append(encodedImageString.charAt(i));
813         }
814         byte[] labelBytes = Base64.base64Decode(sb.toString().getBytes());
815         
816         if (labelBytes != null) {
817             // store in db blob
818
shipmentPackageRouteSeg.setBytes("labelImage", labelBytes);
819         } else {
820             Debug.log("Failed to either decode returned DHL label or no data found in eCommerce/Shipment/Label/Image.");
821             // TODO: VOID
822
}
823         
824         shipmentPackageRouteSeg.set("trackingCode", trackingNumber);
825         shipmentPackageRouteSeg.set("labelHtml", sb.toString());
826         shipmentPackageRouteSeg.store();
827         
828         shipmentRouteSegment.set("trackingIdNumber", trackingNumber);
829         shipmentRouteSegment.put("carrierServiceStatusId", "SHRSCS_CONFIRMED");
830         shipmentRouteSegment.store();
831         
832         return ServiceUtil.returnSuccess("DHL Shipment Confirmed.");
833     }
834
835     private static double getWeight(List JavaDoc shippableItemInfo) {
836         double totalWeight = 0;
837         if (shippableItemInfo != null) {
838             Iterator JavaDoc sii = shippableItemInfo.iterator();
839             while (sii.hasNext()) {
840                 Map JavaDoc itemInfo = (Map JavaDoc) sii.next();
841                 double weight = ((Double JavaDoc) itemInfo.get("weight")).doubleValue();
842                 totalWeight = totalWeight + weight;
843             }
844         }
845         return totalWeight;
846     }
847
848     public static Document JavaDoc createAccessRequestDocument() {
849         return createAccessRequestDocument(shipmentPropertiesFile);
850     }
851
852     public static Document JavaDoc createAccessRequestDocument(String JavaDoc props) {
853         Document JavaDoc eCommerceRequestDocument = UtilXml
854                 .makeEmptyXmlDocument("eCommerce");
855         Element JavaDoc eCommerceRequesElement = eCommerceRequestDocument
856                 .getDocumentElement();
857         eCommerceRequesElement.setAttribute("version", UtilProperties
858                 .getPropertyValue(props, "shipment.dhl.head.version"));
859         eCommerceRequesElement.setAttribute("action", UtilProperties
860                 .getPropertyValue(props, "shipment.dhl.head.action"));
861         Element JavaDoc requestorRequestElement = UtilXml.addChildElement(
862                 eCommerceRequesElement, "Requestor", eCommerceRequestDocument);
863         UtilXml
864                 .addChildElementValue(requestorRequestElement, "ID",
865                         UtilProperties.getPropertyValue(props,
866                                 "shipment.dhl.access.userid"),
867                         eCommerceRequestDocument);
868         UtilXml.addChildElementValue(requestorRequestElement, "Password",
869                 UtilProperties.getPropertyValue(props,
870                         "shipment.dhl.access.password"),
871                 eCommerceRequestDocument);
872
873         return eCommerceRequestDocument;
874     }
875
876     public static void handleErrors(Element JavaDoc responseElement, List JavaDoc errorList) {
877         Element JavaDoc faultsElement = UtilXml.firstChildElement(responseElement,
878                 "Faults");
879         List JavaDoc faultElements = UtilXml.childElementList(faultsElement, "Fault");
880         if (UtilValidate.isNotEmpty(faultElements)) {
881             Iterator JavaDoc errorElementIter = faultElements.iterator();
882             while (errorElementIter.hasNext()) {
883                 StringBuffer JavaDoc errorMessageBuf = new StringBuffer JavaDoc();
884                 Element JavaDoc errorElement = (Element JavaDoc) errorElementIter.next();
885
886                 String JavaDoc errorCode = UtilXml.childElementValue(errorElement,
887                         "Code");
888                 String JavaDoc errorDescription = UtilXml.childElementValue(
889                         errorElement, "Desc");
890                 String JavaDoc errorSource = UtilXml.childElementValue(errorElement,
891                         "Source");
892                 if (UtilValidate.isEmpty(errorSource)) {
893                     errorSource = UtilXml.childElementValue(errorElement,
894                             "Context");
895                 }
896                 errorMessageBuf.append("An error occurred [code:");
897                 errorMessageBuf.append(errorCode);
898                 errorMessageBuf.append("] ");
899                 errorMessageBuf.append(" [Description:");
900                 errorMessageBuf.append(errorDescription);
901                 errorMessageBuf.append("] ");
902                 errorMessageBuf.append(". ");
903                 if (UtilValidate.isNotEmpty(errorSource)) {
904                     errorMessageBuf.append("The error was at Element [");
905                     errorMessageBuf.append(errorSource);
906                     errorMessageBuf.append("]");
907                 }
908                 errorList.add(errorMessageBuf.toString());
909             }
910         }
911     }
912 }
913
914
915 class DhlConnectException extends GeneralException {
916     DhlConnectException() {
917         super();
918     }
919
920     DhlConnectException(String JavaDoc msg) {
921         super(msg);
922     }
923
924     DhlConnectException(Throwable JavaDoc t) {
925         super(t);
926     }
927
928     DhlConnectException(String JavaDoc msg, Throwable JavaDoc t) {
929         super(msg, t);
930     }
931 }
932
Popular Tags