All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.prowidesoftware.swift.model.SwiftBlock2Output Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2006-2023 Prowide
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.prowidesoftware.swift.model;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Objects;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.time.DateFormatUtils;

/**
 * Base class for SWIFT Application Header Block (block 2)
 * for OUTPUT (from SWIFT).
* This block is used to construct messages that have been * output from the SWIFT network. From the application point * of view, it correspond to the RECEIVED messages.

* *

It's value is fixed-length and continuous with no field delimiters. * This class contains its elements as individual attributes for * easier management of the block value. * *

For a received message, a message being output from SWIFT, the * SwiftBlock2Output includes explicit information regarding the MIR. * This is sometimes confusing because it is an output block with an * input reference. The important thing to understand here is that the * MIR information is related to the original sender of the message that * has been received. The attributes of this header (block 2 output) are * explicitly documented as MIR information by SWIFT. * *

The MOR itself could be created combining information from block 1 * and 2 but it usually does not make sense. * * @see MIR * @since 4.0 */ // TODO: add parameter checks (Validate.*) and complete javadocs public class SwiftBlock2Output extends SwiftBlock2 implements Serializable { private static final long serialVersionUID = 6067091531833134527L; /** * String of 4 characters containing the input time with respect to the sender */ private String senderInputTime; /** * Date part of the MIR in YYMMDD format. */ private String MIRDate; /** * String of 12 characters containing the logical terminal field of the MIR * (address of the sender of the message). */ private String MIRLogicalTerminal; /** * String of 4 characters containing the session number field of the MIR. */ private String MIRSessionNumber; /** * String of 6 characters containing the sequence number field of the MIR. */ private String MIRSequenceNumber; /** * String of 6 characters containing the Output date local * to the receiver, written in the following format: YYMMDD */ private String receiverOutputDate; /** * String of 4 characters containing the Output time local * to the receiver, written in the following format: HHMM */ private String receiverOutputTime; /** * Constructor for specific values * * @param messageType the message type * @param senderInputTime the input time * @param MIRDate date * @param MIRLogicalTerminal logical terminal * @param MIRSessionNumber session number * @param MIRSequenceNumber message sequence number * @param receiverOutputDate receiver date * @param receiverOutputTime receiver time * @param messagePriority the message priority (S=system, U=urgent, N=normal) */ public SwiftBlock2Output( final String messageType, final String senderInputTime, final String MIRDate, final String MIRLogicalTerminal, final String MIRSessionNumber, final String MIRSequenceNumber, final String receiverOutputDate, final String receiverOutputTime, final String messagePriority) { this.output = true; this.messageType = messageType; this.senderInputTime = senderInputTime; this.MIRDate = MIRDate; this.MIRLogicalTerminal = MIRLogicalTerminal; this.MIRSessionNumber = MIRSessionNumber; this.MIRSequenceNumber = MIRSequenceNumber; this.receiverOutputDate = receiverOutputDate; this.receiverOutputTime = receiverOutputTime; this.messagePriority = messagePriority; } /** * Creates the block with lenient false, meaning it expects a fixed length value. * Example of supported values:
* "O1001200970103BANKBEBBAXXX22221234569701031201N" or "2:O1001200970103BANKBEBBAXXX22221234569701031201N" * * @param value a fixed length string of 46 (starting with 'O') or 49 (starting with '2:O') characters containing the blocks value * @throws IllegalArgumentException if parameter is not 47 or 49 characters * @see #SwiftBlock2Output(String, boolean) */ public SwiftBlock2Output(final String value) { this(value, false); } /** * Creates a block 2 output object setting attributes by parsing the string argument containing the blocks value. * This value can be in different flavors because some fields are optional.
* * @param value string containing the entire blocks value * @param lenient if true the value will be parsed with a best effort heuristic, if false it will throw a IllegalArgumentException if the value has an invalid total size * @see #setValue(String, boolean) * @since 7.7 */ public SwiftBlock2Output(final String value, boolean lenient) { this.setValue(value, lenient); } /** * Default Constructor */ public SwiftBlock2Output() {} /** * Copy constructor * * @param block an existing block2 to copy * @since 7.10.4 */ public SwiftBlock2Output(SwiftBlock2Output block) { this( block.getMessageType(), block.getSenderInputTime(), block.getMIRDate(), block.getMIRLogicalTerminal(), block.getMIRSessionNumber(), block.getMIRSequenceNumber(), block.getReceiverOutputDate(), block.getReceiverOutputTime(), block.getMessagePriority()); } /** * This method deserializes the JSON data into an incoming (output) block 2 object. * * @see #toJson() * @since 7.9.8 */ public static SwiftBlock2Output fromJson(String json) { final Gson gson = new GsonBuilder().create(); return gson.fromJson(json, SwiftBlock2Output.class); } /** * Returns the input time with respect to the sender * * @return 4 numbers HHMM */ public String getSenderInputTime() { return senderInputTime; } /** * Sets the input time with respect to the sender * * @param senderInputTime 4 numbers HHMM */ public void setSenderInputTime(final String senderInputTime) { this.senderInputTime = senderInputTime; } /** * Gets the date the sender sent the message to SWIFT, * from the MIR field, in the format YYMMDD * * @return String with 6 numbers */ public String getMIRDate() { return this.MIRDate; } /** * Sets the date the sender sent the message to SWIFT, from the MIR field * * @param MIRDate 6 numbers with date in format YYMMDD */ public void setMIRDate(final String MIRDate) { this.MIRDate = MIRDate; } /** * Sets the date the sender sent the message to SWIFT, from the MIR field * * @param cal the calendar to format date from * @since 9.1.3 */ public void setMIRDate(Calendar cal) { String yymmdd = DateFormatUtils.format(cal.getTime(), "yyMMdd"); setMIRDate(yymmdd); } /** * Creates a full LT address using the parameter BIC code and a default LT identifier, * and sets the resulting address as MIR logical terminal address. * * @see #setMIRLogicalTerminal(LogicalTerminalAddress) * @since 7.6 */ public void setSender(final BIC bic) { setMIRLogicalTerminal(new LogicalTerminalAddress(bic.getBic11())); } /** * Completes if necessary and sets the LT address of the sender * as MIR logical terminal address.
* The sender addresses will be filled with proper default LT identifier and branch codes if not provided. * * @see #setMIRLogicalTerminal(LogicalTerminalAddress) * @since 7.6 */ public void setSender(final String sender) { setMIRLogicalTerminal(new LogicalTerminalAddress(sender)); } /** * Gets the the full LT address of the sender of the * message, from the MIR field, for example: BANKBEBBAXXX * * @return LT address */ public String getMIRLogicalTerminal() { return this.MIRLogicalTerminal; } /** * Sets the the full LT address of the sender of the message. * * @param MIRLogicalTerminal 12 characters full LT address */ public void setMIRLogicalTerminal(final String MIRLogicalTerminal) { this.MIRLogicalTerminal = MIRLogicalTerminal; } /** * Sets the the full LT address of the sender of the message. * * @param MIRLogicalTerminal 12 characters full LT address * @see LogicalTerminalAddress#getSenderLogicalTerminalAddress() * @since 7.6 */ public void setMIRLogicalTerminal(final LogicalTerminalAddress MIRLogicalTerminal) { this.MIRLogicalTerminal = MIRLogicalTerminal.getSenderLogicalTerminalAddress(); } /** * Gets the sender's BIC code.
* For output message the sender address is contained in this block2 * and not in the header block 1 as for input messages. * * @return sender BIC address * @see BIC * @since 7.6 */ public BIC getSenderBIC() { return new BIC(this.MIRLogicalTerminal); } /** * Gets the date the sender session number, * from the MIR field, in the format NNNN * * @return 4 numbers */ public String getMIRSessionNumber() { return this.MIRSessionNumber; } /** * Sets the session number field of the MIR * * @param MIRSessionNumber 4 numbers */ public void setMIRSessionNumber(final String MIRSessionNumber) { this.MIRSessionNumber = MIRSessionNumber; } /** * Gets the date the sender sequence number, * from the MIR field, in the format NNNNNN * * @return 6 numbers */ public String getMIRSequenceNumber() { return MIRSequenceNumber; } /** * Sets the sequence number field of the MIR * * @param MIRSequenceNumber 6 numbers */ public void setMIRSequenceNumber(final String MIRSequenceNumber) { this.MIRSequenceNumber = MIRSequenceNumber; } /** * Gets the full MIR (Message Input Reference) string of 28 * characters containing the sender's date, LT address, * session and sequence:
* for example YYMMDDBANKBEBBAXXX2222123456
* * @return a String with MIR, returns null if all MIR components are null */ public String getMIR() { if (MIRDate == null && MIRLogicalTerminal == null && MIRSessionNumber == null && MIRSequenceNumber == null) { return null; } final StringBuilder v = new StringBuilder(); if (MIRDate != null) { v.append(MIRDate); } if (MIRLogicalTerminal != null) { v.append(MIRLogicalTerminal); } if (MIRSessionNumber != null) { v.append(MIRSessionNumber); } if (MIRSequenceNumber != null) { v.append(MIRSequenceNumber); } return v.toString(); } /** * Sets the full MIR (Message Input Reference) from a fixed length (28 characters) string containing the complete MIR value.
* * @param mir complete MIR string value, a fixed length (28 characters) string containing the MIR value * @throws IllegalArgumentException if parameter has an invalid total size. * @see #setMIR(String, boolean) */ public void setMIR(final String mir) { setMIR(mir, false); } /** * Sets the MIR (Message Input Reference) attributes by parsing the string argument containing the complete MIR value.
* For example YYMMDDBANKBEBBAXXX2222123456
* * @param mir complete MIR string * @param lenient if true the value will be parsed with a best effort heuristic, if false it will throw a IllegalArgumentException if the value has an invalid total size */ public void setMIR(final String mir, boolean lenient) { if (!lenient) { Objects.requireNonNull(mir); Validate.isTrue( mir.length() == 28, "expected a 28 characters string for MIR value and found a " + mir.length() + " string:" + mir); } if (mir != null) { int offset = 0; int len; len = 6; this.setMIRDate(getValuePart(mir, offset, len)); offset += len; len = 12; this.setMIRLogicalTerminal(getValuePart(mir, offset, len)); offset += len; len = 4; this.setMIRSessionNumber(getValuePart(mir, offset, len)); offset += len; if (lenient) { // get all remaining text this.setMIRSequenceNumber(getValuePart(mir, offset, mir.length())); } else { len = 6; this.setMIRSequenceNumber(getValuePart(mir, offset, len)); } } } /** * Gets the Output date local to the receiver * * @return 6 characters in format YYMMDD */ public String getReceiverOutputDate() { return receiverOutputDate; } /** * Sets the Output date local to the receiver, written in the following format: YYMMDD * * @param receiverOutputDate 6 characters in format YYMMDD */ public void setReceiverOutputDate(final String receiverOutputDate) { this.receiverOutputDate = receiverOutputDate; } /** * Gets the Output time local to the receiver, written in the following format: HHMM * * @return String with 4 numbers */ public String getReceiverOutputTime() { return receiverOutputTime; } /** * Sets the Output time local to the receiver, written in the following format: HHMM * * @param receiverOutputTime String with 4 numbers */ public void setReceiverOutputTime(final String receiverOutputTime) { this.receiverOutputTime = receiverOutputTime; } /** * Sets the receiver output date and receiver output time fields from a Calendar * * @param cal the calendar to format date and time from * @since 9.1.3 */ public void setReceiverOutputDateTime(Calendar cal) { String yymmdd = DateFormatUtils.format(cal.getTime(), "yyMMdd"); String hhmm = DateFormatUtils.format(cal.getTime(), "HHmm"); setReceiverOutputDate(yymmdd); setReceiverOutputTime(hhmm); } /** * Tell if this block is empty or not. * This block is considered to be empty if all its attributes are set to null. * * @return true if all fields are null and false in other case */ @Override public boolean isEmpty() { return messageType == null && senderInputTime == null && getMIR() == null && receiverOutputDate == null && receiverOutputTime == null && messagePriority == null; } /** * Gets the fixed length block 2 value, as a result of * concatenating its individual elements as follow:
* Message Type + * Sender Input Time + * MIR + * Receiver Output Date + * Receiver Output Time + * Message Priority. */ @Override public String getValue() { if (isEmpty()) { return null; } final StringBuilder v = new StringBuilder("O"); if (messageType != null) { v.append(messageType); } if (senderInputTime != null) { v.append(senderInputTime); } if (getMIR() != null) { v.append(getMIR()); } if (receiverOutputDate != null) { v.append(receiverOutputDate); } if (receiverOutputTime != null) { v.append(receiverOutputTime); } if (messagePriority != null) { v.append(messagePriority); } return v.toString(); } /** * Sets the block's attributes by parsing the fixed length string argument.
* * @param value a fixed length (between 46 and 49) string containing the blocks' value * @throws IllegalArgumentException if parameter has an invalid total size. * @see #setValue(String, boolean) */ @Override public void setValue(final String value) { setValue(value, false); } /** * @see #getValue() */ @Override public String getBlockValue() { return getValue(); } /** * @see #setValue(String) */ @Override public void setBlockValue(final String value) { setValue(value); } /** * Sets the block's attributes by parsing the string argument containing the blocks value.
* This value can be in different flavors because some fields are optional.
* Example of supported values:
*

     *   "O1001200970103BANKBEBBAXXX22221234569701031201" (46) or
     *   "2:O1001200970103BANKBEBBAXXX22221234569701031201" (48)   // used for service/system messages
     *   "O1001200970103BANKBEBBAXXX22221234569701031201N" (47) or
     *   "2:O1001200970103BANKBEBBAXXX22221234569701031201N" (49)
     * 

* * @param value string containing the entire blocks value * @param lenient if true the value will be parsed with a best effort heuristic, if false it will throw a IllegalArgumentException if the value has an invalid total size */ public void setValue(final String value, boolean lenient) { if (lenient) { // leave all attributes as null (cleaning defaults) clean(); } else { // check parameters Objects.requireNonNull(value, "value must not be null"); } if (value != null) { int slen = value.length(); if (!lenient) { // check parameters Objects.requireNonNull(value, "value must not be null"); Validate.isTrue( slen == 46 || slen == 48 || slen == 47 || slen == 49, "expected a string value of 46 and up to 49 chars and obtained a " + slen + " chars string: '" + value + "'"); } // figure out the starting point and check the input value has proper optional int offset = 0; if (value.startsWith("2:")) { // accept 2:... offset = 2; } slen -= offset; if (!lenient && slen != 46 && slen != 47) { throw new IllegalArgumentException("Value must match: O




© 2015 - 2024 Weber Informatics LLC | Privacy Policy