001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.smpp;
018    
019    import java.io.UnsupportedEncodingException;
020    import java.util.Arrays;
021    import java.util.Date;
022    import java.util.List;
023    
024    import org.apache.camel.Exchange;
025    import org.apache.camel.Message;
026    import org.jsmpp.bean.AlertNotification;
027    import org.jsmpp.bean.Command;
028    import org.jsmpp.bean.DataSm;
029    import org.jsmpp.bean.DeliverSm;
030    import org.jsmpp.bean.DeliveryReceipt;
031    import org.jsmpp.bean.OptionalParameter;
032    import org.jsmpp.bean.OptionalParameter.OctetString;
033    import org.jsmpp.bean.OptionalParameters;
034    import org.jsmpp.bean.SubmitSm;
035    import org.jsmpp.util.AbsoluteTimeFormatter;
036    import org.jsmpp.util.TimeFormatter;
037    
038    /**
039     * A Strategy used to convert between a Camel {@link Exchange} and
040     * {@link SmppMessage} to and from a SMPP {@link Command}
041     * 
042     * @version 
043     */
044    public class SmppBinding {
045    
046        public static final String SEQUENCE_NUMBER = "CamelSmppSequenceNumber";
047        public static final String SUBMITTED = "CamelSmppSubmitted";
048        public static final String SUBMIT_DATE = "CamelSmppSubmitDate";
049        public static final String ERROR = "CamelSmppError";
050        public static final String DONE_DATE = "CamelSmppDoneDate";
051        public static final String DELIVERED = "CamelSmppDelivered";
052        public static final String COMMAND_ID = "CamelSmppCommandId";
053        public static final String COMMAND_STATUS = "CamelSmppCommandStatus";
054        public static final String ID = "CamelSmppId";
055        public static final String REPLACE_IF_PRESENT_FLAG = "CamelSmppReplaceIfPresentFlag";
056        public static final String VALIDITY_PERIOD = "CamelSmppValidityPeriod";
057        public static final String SCHEDULE_DELIVERY_TIME = "CamelSmppScheduleDeliveryTime";
058        public static final String PRIORITY_FLAG = "CamelSmppPriorityFlag";
059        public static final String PROTOCOL_ID = "CamelSmppProtocolId";
060        public static final String REGISTERED_DELIVERY = "CamelSmppRegisteredDelivery";
061        public static final String SERVICE_TYPE = "CamelSmppServiceType";
062        public static final String SOURCE_ADDR_NPI = "CamelSmppSourceAddrNpi";
063        public static final String SOURCE_ADDR_TON = "CamelSmppSourceAddrTon";
064        public static final String SOURCE_ADDR = "CamelSmppSourceAddr";
065        public static final String DEST_ADDR_NPI = "CamelSmppDestAddrNpi";
066        public static final String DEST_ADDR_TON = "CamelSmppDestAddrTon";
067        public static final String DEST_ADDR = "CamelSmppDestAddr";
068        public static final String ESME_ADDR_NPI = "CamelSmppEsmeAddrNpi";
069        public static final String ESME_ADDR_TON = "CamelSmppEsmeAddrTon";
070        public static final String ESME_ADDR = "CamelSmppEsmeAddr";
071        public static final String FINAL_STATUS = "CamelSmppStatus";
072        public static final String DATA_CODING = "CamelSmppDataCoding";
073        public static final String MESSAGE_TYPE = "CamelSmppMessageType";
074    
075        private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter();
076    
077        private SmppConfiguration configuration;
078    
079        public SmppBinding() {
080            this.configuration = new SmppConfiguration();
081        }
082    
083        public SmppBinding(SmppConfiguration configuration) {
084            this.configuration = configuration;
085        }
086    
087        /**
088         * Create the SubmitSm object from the inbound exchange
089         * 
090         * @throws UnsupportedEncodingException if the encoding is not supported
091         */
092        public SubmitSm createSubmitSm(Exchange exchange) throws UnsupportedEncodingException {
093            Message in = exchange.getIn();
094            String body = exchange.getIn().getBody(String.class);
095            
096            SubmitSm submitSm = new SubmitSm();
097            
098            if (body != null) {
099                byte[] shortMessage = body.getBytes(configuration.getEncoding());
100                
101                if (shortMessage.length < 255) {
102                    submitSm.setShortMessage(shortMessage);
103                    // To avoid the NPE error
104                    submitSm.setOptionalParametes(new OptionalParameter[]{});
105                } else {
106                    submitSm.setShortMessage(new byte[0]);
107                    OptionalParameter messagePayloadTLV = OptionalParameters.deserialize(OptionalParameter.Tag.MESSAGE_PAYLOAD.code(), shortMessage);
108    
109                    submitSm.setOptionalParametes(messagePayloadTLV);
110                }
111            }
112    
113            if (in.getHeaders().containsKey(DEST_ADDR)) {
114                submitSm.setDestAddress(in.getHeader(DEST_ADDR, String.class));
115            } else {
116                submitSm.setDestAddress(configuration.getDestAddr());
117            }
118    
119            if (in.getHeaders().containsKey(DEST_ADDR_TON)) {
120                submitSm.setDestAddrTon(in.getHeader(DEST_ADDR_TON, Byte.class));
121            } else {
122                submitSm.setDestAddrTon(configuration.getDestAddrTon());
123            }
124    
125            if (in.getHeaders().containsKey(DEST_ADDR_NPI)) {
126                submitSm.setDestAddrNpi(in.getHeader(DEST_ADDR_NPI, Byte.class));
127            } else {
128                submitSm.setDestAddrNpi(configuration.getDestAddrNpi());
129            }
130    
131            if (in.getHeaders().containsKey(SOURCE_ADDR)) {
132                submitSm.setSourceAddr(in.getHeader(SOURCE_ADDR, String.class));
133            } else {
134                submitSm.setSourceAddr(configuration.getSourceAddr());
135            }
136    
137            if (in.getHeaders().containsKey(SOURCE_ADDR_TON)) {
138                submitSm.setSourceAddrTon(in.getHeader(SOURCE_ADDR_TON, Byte.class));
139            } else {
140                submitSm.setSourceAddrTon(configuration.getSourceAddrTon());
141            }
142    
143            if (in.getHeaders().containsKey(SOURCE_ADDR_NPI)) {
144                submitSm.setSourceAddrNpi(in.getHeader(SOURCE_ADDR_NPI, Byte.class));
145            } else {
146                submitSm.setSourceAddrNpi(configuration.getSourceAddrNpi());
147            }
148    
149            if (in.getHeaders().containsKey(SERVICE_TYPE)) {
150                submitSm.setServiceType(in.getHeader(SERVICE_TYPE, String.class));
151            } else {
152                submitSm.setServiceType(configuration.getServiceType());
153            }
154    
155            if (in.getHeaders().containsKey(REGISTERED_DELIVERY)) {
156                submitSm.setRegisteredDelivery(in.getHeader(REGISTERED_DELIVERY, Byte.class));
157            } else {
158                submitSm.setRegisteredDelivery(configuration.getRegisteredDelivery());
159            }
160    
161            if (in.getHeaders().containsKey(PROTOCOL_ID)) {
162                submitSm.setProtocolId(in.getHeader(PROTOCOL_ID, Byte.class));
163            } else {
164                submitSm.setProtocolId(configuration.getProtocolId());
165            }
166    
167            if (in.getHeaders().containsKey(PRIORITY_FLAG)) {
168                submitSm.setPriorityFlag(in.getHeader(PRIORITY_FLAG, Byte.class));
169            } else {
170                submitSm.setPriorityFlag(configuration.getPriorityFlag());
171            }
172    
173            if (in.getHeaders().containsKey(SCHEDULE_DELIVERY_TIME)) {
174                submitSm.setScheduleDeliveryTime(timeFormatter.format(in.getHeader(SCHEDULE_DELIVERY_TIME, Date.class)));
175            } 
176    
177            if (in.getHeaders().containsKey(VALIDITY_PERIOD)) {
178                submitSm.setValidityPeriod(timeFormatter.format(in.getHeader(VALIDITY_PERIOD, Date.class)));
179            }
180    
181            if (in.getHeaders().containsKey(REPLACE_IF_PRESENT_FLAG)) {
182                submitSm.setReplaceIfPresent(in.getHeader(REPLACE_IF_PRESENT_FLAG, Byte.class));
183            } else {
184                submitSm.setReplaceIfPresent(configuration.getReplaceIfPresentFlag());
185            }
186            
187            if (in.getHeaders().containsKey(DATA_CODING)) {
188                submitSm.setDataCoding(in.getHeader(DATA_CODING, Byte.class));
189            } else {
190                submitSm.setDataCoding(configuration.getDataCoding());
191            }
192    
193            return submitSm;
194        }
195    
196        /**
197         * Create a new SmppMessage from the inbound alert notification
198         */
199        public SmppMessage createSmppMessage(AlertNotification alertNotification) {
200            SmppMessage smppMessage = new SmppMessage(alertNotification, configuration);
201    
202            smppMessage.setHeader(MESSAGE_TYPE, SmppMessageType.AlertNotification.toString());
203            smppMessage.setHeader(SEQUENCE_NUMBER, alertNotification.getSequenceNumber());
204            smppMessage.setHeader(COMMAND_ID, alertNotification.getCommandId());
205            smppMessage.setHeader(COMMAND_STATUS, alertNotification.getCommandStatus());
206            smppMessage.setHeader(SOURCE_ADDR, alertNotification.getSourceAddr());
207            smppMessage.setHeader(SOURCE_ADDR_NPI, alertNotification.getSourceAddrNpi());
208            smppMessage.setHeader(SOURCE_ADDR_TON, alertNotification.getSourceAddrTon());
209            smppMessage.setHeader(ESME_ADDR, alertNotification.getEsmeAddr());
210            smppMessage.setHeader(ESME_ADDR_NPI, alertNotification.getEsmeAddrNpi());
211            smppMessage.setHeader(ESME_ADDR_TON, alertNotification.getEsmeAddrTon());
212    
213            return smppMessage;
214        }
215    
216        /**
217         * Create a new SmppMessage from the inbound deliver sm or deliver receipt
218         */
219        public SmppMessage createSmppMessage(DeliverSm deliverSm) throws Exception {
220            SmppMessage smppMessage = new SmppMessage(deliverSm, configuration);
221    
222            if (deliverSm.isSmscDeliveryReceipt()) {
223                smppMessage.setHeader(MESSAGE_TYPE, SmppMessageType.DeliveryReceipt.toString());
224                DeliveryReceipt smscDeliveryReceipt = deliverSm.getShortMessageAsDeliveryReceipt();
225                smppMessage.setBody(smscDeliveryReceipt.getText());
226    
227                smppMessage.setHeader(ID, smscDeliveryReceipt.getId());
228                smppMessage.setHeader(DELIVERED, smscDeliveryReceipt.getDelivered());
229                smppMessage.setHeader(DONE_DATE, smscDeliveryReceipt.getDoneDate());
230                if (!"000".equals(smscDeliveryReceipt.getError())) {
231                    smppMessage.setHeader(ERROR, smscDeliveryReceipt.getError());
232                }
233                smppMessage.setHeader(SUBMIT_DATE, smscDeliveryReceipt.getSubmitDate());
234                smppMessage.setHeader(SUBMITTED, smscDeliveryReceipt.getSubmitted());
235                smppMessage.setHeader(FINAL_STATUS, smscDeliveryReceipt.getFinalStatus());
236            } else {
237                smppMessage.setHeader(MESSAGE_TYPE, SmppMessageType.DeliverSm.toString());
238                if (deliverSm.getShortMessage() != null) {
239                    smppMessage.setBody(String.valueOf(new String(deliverSm.getShortMessage(),
240                            configuration.getEncoding())));
241                } else if (deliverSm.getOptionalParametes() != null && deliverSm.getOptionalParametes().length > 0) {
242                    List<OptionalParameter> oplist = Arrays.asList(deliverSm.getOptionalParametes());
243    
244                    for (OptionalParameter optPara : oplist) {
245                        if (OptionalParameter.Tag.MESSAGE_PAYLOAD.code() == optPara.tag && OctetString.class.isInstance(optPara)) {
246                            smppMessage.setBody(((OctetString) optPara).getValueAsString());
247                            break;
248                        }
249                    }
250                }
251    
252                smppMessage.setHeader(SEQUENCE_NUMBER, deliverSm.getSequenceNumber());
253                smppMessage.setHeader(COMMAND_ID, deliverSm.getCommandId());
254                smppMessage.setHeader(SOURCE_ADDR, deliverSm.getSourceAddr());
255                smppMessage.setHeader(DEST_ADDR, deliverSm.getDestAddress());
256                smppMessage.setHeader(SCHEDULE_DELIVERY_TIME, deliverSm.getScheduleDeliveryTime());
257                smppMessage.setHeader(VALIDITY_PERIOD, deliverSm.getValidityPeriod());
258                smppMessage.setHeader(SERVICE_TYPE, deliverSm.getServiceType());
259            }
260    
261            return smppMessage;
262        }
263        
264        public SmppMessage createSmppMessage(DataSm dataSm, String smppMessageId) {
265            SmppMessage smppMessage = new SmppMessage(dataSm, configuration);
266    
267            smppMessage.setHeader(MESSAGE_TYPE, SmppMessageType.DataSm.toString());
268            smppMessage.setHeader(ID, smppMessageId);
269            smppMessage.setHeader(SEQUENCE_NUMBER, dataSm.getSequenceNumber());
270            smppMessage.setHeader(COMMAND_ID, dataSm.getCommandId());
271            smppMessage.setHeader(COMMAND_STATUS, dataSm.getCommandStatus());
272            smppMessage.setHeader(SOURCE_ADDR, dataSm.getSourceAddr());
273            smppMessage.setHeader(SOURCE_ADDR_NPI, dataSm.getSourceAddrNpi());
274            smppMessage.setHeader(SOURCE_ADDR_TON, dataSm.getSourceAddrTon());
275            smppMessage.setHeader(DEST_ADDR, dataSm.getDestAddress());
276            smppMessage.setHeader(DEST_ADDR_NPI, dataSm.getDestAddrNpi());
277            smppMessage.setHeader(DEST_ADDR_TON, dataSm.getDestAddrTon());
278            smppMessage.setHeader(SERVICE_TYPE, dataSm.getServiceType());
279            smppMessage.setHeader(REGISTERED_DELIVERY, dataSm.getRegisteredDelivery());
280            smppMessage.setHeader(DATA_CODING, dataSm.getDataCoding());
281    
282            return smppMessage;
283        }
284        
285        /**
286         * Returns the current date. Externalized for better test support.
287         * 
288         * @return the current date
289         */
290        Date getCurrentDate() {
291            return new Date();
292        }
293    
294        /**
295         * Returns the smpp configuration
296         * 
297         * @return the configuration
298         */
299        public SmppConfiguration getConfiguration() {
300            return configuration;
301        }
302    
303        /**
304         * Set the smpp configuration.
305         * 
306         * @param configuration smppConfiguration
307         */
308        public void setConfiguration(SmppConfiguration configuration) {
309            this.configuration = configuration;
310        }
311    }