Skip to content

Commit cdb483d

Browse files
authored
Merge pull request #40 from ebics-java/zkb-xe2
support BTUOrderParams for EBICS 3.0 request
2 parents e4e6787 + 207479a commit cdb483d

10 files changed

+219
-175
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
<artifactId>maven-compiler-plugin</artifactId>
100100
<version>3.14.1</version>
101101
<configuration>
102-
<release>11</release>
102+
<release>17</release>
103103
</configuration>
104104
</plugin>
105105
<plugin>

src/main/java/org/kopi/ebics/client/EbicsClient.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public void revokeSubscriber(User user, Product product) throws Exception {
372372
try {
373373
keyManager.lockAccess();
374374
} catch (Exception e) {
375-
log.error(messages.getString("spr.send.error", userId), e);
375+
log.error(messages.getString("spr.send.error", userId));
376376
throw e;
377377
}
378378

@@ -383,7 +383,7 @@ public void revokeSubscriber(User user, Product product) throws Exception {
383383
* Sends a file to the ebics bank server
384384
* @throws Exception
385385
*/
386-
public void sendFile(File file, User user, Product product, EbicsOrderType orderType) throws Exception {
386+
public void sendFile(File file, User user, Product product, EbicsOrderType orderType, EbicsUploadParams params) throws Exception {
387387
EbicsSession session = createSession(user, product);
388388

389389
FileTransfer transferManager = new FileTransfer(session);
@@ -392,16 +392,28 @@ public void sendFile(File file, User user, Product product, EbicsOrderType order
392392
configuration.getTransferTraceDirectory(user));
393393

394394
try {
395-
transferManager.sendFile(IOUtils.getFileContent(file), orderType);
395+
transferManager.sendFile(IOUtils.getFileContent(file), orderType, params);
396396
} catch (IOException | EbicsException e) {
397397
log
398-
.error(messages.getString("upload.file.error", file.getAbsolutePath()), e);
398+
.error(messages.getString("upload.file.error", file.getAbsolutePath()));
399399
throw e;
400400
}
401401
}
402402

403+
public void sendFile(File file, EbicsOrderType orderType, EbicsUploadParams params) throws Exception {
404+
sendFile(file, defaultUser, defaultProduct, orderType, params);
405+
}
406+
403407
public void sendFile(File file, EbicsOrderType orderType) throws Exception {
404-
sendFile(file, defaultUser, defaultProduct, orderType);
408+
EbicsUploadParams params;
409+
if (orderType == OrderType.XE2) {
410+
var orderParams = new EbicsUploadParams.OrderParams("MCT", "CH", null, "pain.001",
411+
"03", true);
412+
params = new EbicsUploadParams(null, orderParams);
413+
} else {
414+
params = new EbicsUploadParams(defaultUser.getPartner().nextOrderId(), null);
415+
}
416+
sendFile(file, defaultUser, defaultProduct, orderType, params);
405417
}
406418

407419
public void fetchFile(File file, User user, Product product, EbicsOrderType orderType,
@@ -660,8 +672,7 @@ public static void main(String[] args) throws Exception {
660672
OrderType.XE2, OrderType.CCT);
661673
for (EbicsOrderType type : sendFileOrders) {
662674
if (hasOption(cmd, type)) {
663-
client.sendFile(new File(inputFileValue), client.defaultUser,
664-
client.defaultProduct, type);
675+
client.sendFile(new File(inputFileValue), type);
665676
break;
666677
}
667678
}

src/main/java/org/kopi/ebics/client/FileTransfer.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,11 @@ public FileTransfer(EbicsSession session) {
9191
* @throws IOException
9292
* @throws EbicsException
9393
*/
94-
public void sendFile(byte[] content, EbicsOrderType orderType)
94+
public void sendFile(byte[] content, EbicsOrderType orderType, EbicsUploadParams params)
9595
throws IOException, EbicsException
9696
{
9797
HttpRequestSender sender = new HttpRequestSender(session);
98-
UploadInitializationRequestElement initializer = new UploadInitializationRequestElement(session,
99-
orderType,
100-
content);
98+
var initializer = new UploadInitializationRequestElement(session, orderType, params, content);
10199
initializer.build();
102100
initializer.validate();
103101
session.getConfiguration().getTraceManager().trace(initializer.getUserSignature());

src/main/java/org/kopi/ebics/xml/DefaultEbicsRootElement.java

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
import java.io.OutputStream;
2424
import java.io.PrintStream;
2525
import java.math.BigInteger;
26+
import java.nio.charset.StandardCharsets;
2627
import java.util.ArrayList;
2728
import java.util.HashMap;
2829
import java.util.Iterator;
30+
import java.util.List;
2931
import java.util.Map;
3032

3133
import javax.xml.namespace.QName;
@@ -83,6 +85,10 @@ public byte[] prettyPrint() {
8385
}
8486
}
8587

88+
public String toPrettyString() {
89+
return new String(prettyPrint(), StandardCharsets.UTF_8);
90+
}
91+
8692
/**
8793
* Inserts a schema location to the current ebics root element.
8894
* @param namespaceURI the name space URI
@@ -96,14 +102,16 @@ public void insertSchemaLocation(String namespaceURI,
96102
String value)
97103
{
98104

99-
XmlCursor cursor = document.newCursor();
100-
while (cursor.hasNextToken()) {
101-
if (cursor.isStart()) {
102-
cursor.toNextToken();
103-
cursor.insertAttributeWithValue(new QName(namespaceURI, localPart, prefix), value);
104-
break;
105-
} else {
106-
cursor.toNextToken();
105+
try (XmlCursor cursor = document.newCursor()) {
106+
while (cursor.hasNextToken()) {
107+
if (cursor.isStart()) {
108+
cursor.toNextToken();
109+
cursor.insertAttributeWithValue(new QName(namespaceURI, localPart, prefix),
110+
value);
111+
break;
112+
} else {
113+
cursor.toNextToken();
114+
}
107115
}
108116
}
109117
}
@@ -143,23 +151,22 @@ public byte[] toByteArray() {
143151

144152
@Override
145153
public void addNamespaceDecl(String prefix, String uri) {
146-
XmlCursor cursor;
147-
148-
cursor = document.newCursor();
149-
while (cursor.hasNextToken()) {
150-
if (cursor.isStart()) {
151-
cursor.toNextToken();
152-
cursor.insertNamespace(prefix, uri);
153-
break;
154-
} else {
155-
cursor.toNextToken();
154+
try (XmlCursor cursor = document.newCursor()) {
155+
while (cursor.hasNextToken()) {
156+
if (cursor.isStart()) {
157+
cursor.toNextToken();
158+
cursor.insertNamespace(prefix, uri);
159+
break;
160+
} else {
161+
cursor.toNextToken();
162+
}
163+
}
156164
}
157-
}
158165
}
159166

160167
@Override
161168
public void validate() throws EbicsException {
162-
ArrayList<XmlError> validationMessages = new ArrayList<>();
169+
List<XmlError> validationMessages = new ArrayList<>();
163170
boolean isValid = document.validate(new XmlOptions().setErrorListener(validationMessages));
164171

165172
if (!isValid) {
@@ -172,22 +179,21 @@ public void validate() throws EbicsException {
172179
message.append(iter.next().getMessage());
173180
}
174181

175-
throw new EbicsException(message.toString());
182+
throw new EbicsException(
183+
"Invalid " + this.getClass().getSimpleName() + ": " + message);
176184
}
177185
}
178186

179187
@Override
180188
public void save(OutputStream out) throws EbicsException {
181-
try {
182-
byte[] element;
183-
184-
element = prettyPrint();
185-
out.write(element);
186-
out.flush();
187-
out.close();
188-
} catch (IOException e) {
189-
throw new EbicsException(e.getMessage());
190-
}
189+
try {
190+
byte[] element = prettyPrint();
191+
out.write(element);
192+
out.flush();
193+
out.close();
194+
} catch (IOException e) {
195+
throw new EbicsException(e.getMessage());
196+
}
191197
}
192198

193199
@Override

src/main/java/org/kopi/ebics/xml/DownloadInitializationRequestElement.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Body;
2727
import org.kopi.ebics.schema.h005.EbicsRequestDocument.EbicsRequest.Header;
2828
import org.kopi.ebics.schema.h005.MutableHeaderType;
29+
import org.kopi.ebics.schema.h005.StandardOrderParamsDocument;
2930
import org.kopi.ebics.schema.h005.StandardOrderParamsType;
3031
import org.kopi.ebics.schema.h005.StaticHeaderOrderDetailsType;
3132
import org.kopi.ebics.schema.h005.StaticHeaderType;
@@ -85,7 +86,8 @@ public void buildInitialization() throws EbicsException {
8586
//FIXME Some banks cannot handle OrderID element in download process. Add parameter in configuration!!!
8687
orderDetails = EbicsXmlFactory.createStaticHeaderOrderDetailsType(null,//session.getUser().getPartner().nextOrderId(),
8788
type,
88-
standardOrderParamsType);
89+
standardOrderParamsType,
90+
StandardOrderParamsDocument.type);
8991

9092
xstatic = EbicsXmlFactory.createStaticHeaderType(session.getBankID(),
9193
nonce,

src/main/java/org/kopi/ebics/xml/EbicsXmlFactory.java

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
import org.ebics.s002.UserSignatureDataDocument;
3434
import org.ebics.s002.UserSignatureDataSigBookType;
3535
import org.kopi.ebics.schema.h005.AuthenticationPubKeyInfoType;
36+
import org.kopi.ebics.schema.h005.BTUOrderParamsDocument;
37+
import org.kopi.ebics.schema.h005.BTUParamsType;
38+
import org.kopi.ebics.schema.h005.DataDigestType;
3639
import org.kopi.ebics.schema.h005.DataEncryptionInfoType.EncryptionPubKeyDigest;
3740
import org.kopi.ebics.schema.h005.DataTransferRequestType;
3841
import org.kopi.ebics.schema.h005.DataTransferRequestType.DataEncryptionInfo;
@@ -51,6 +54,7 @@
5154
import org.kopi.ebics.schema.h005.EncryptionPubKeyInfoType;
5255
import org.kopi.ebics.schema.h005.HIARequestOrderDataDocument;
5356
import org.kopi.ebics.schema.h005.HIARequestOrderDataType;
57+
import org.kopi.ebics.schema.h005.MessageType;
5458
import org.kopi.ebics.schema.h005.MutableHeaderType;
5559
import org.kopi.ebics.schema.h005.MutableHeaderType.SegmentNumber;
5660
import org.kopi.ebics.schema.h005.NoPubKeyDigestsRequestStaticHeaderType;
@@ -59,6 +63,7 @@
5963
import org.kopi.ebics.schema.h005.ParameterDocument.Parameter.Value;
6064
import org.kopi.ebics.schema.h005.ProductElementType;
6165
import org.kopi.ebics.schema.h005.PubKeyInfoType;
66+
import org.kopi.ebics.schema.h005.SignatureFlagType;
6267
import org.kopi.ebics.schema.h005.StandardOrderParamsDocument;
6368
import org.kopi.ebics.schema.h005.StandardOrderParamsType;
6469
import org.kopi.ebics.schema.h005.StaticHeaderOrderDetailsType;
@@ -784,19 +789,19 @@ public static StaticHeaderType createStaticHeaderType(String hostId, byte[] nonc
784789
int numSegments, String partnerId, StaticHeaderType.Product product, String securityMedium,
785790
String userId, Calendar timestamp, StaticHeaderOrderDetailsType orderDetails,
786791
StaticHeaderType.BankPubKeyDigests bankPubKeyDigests) {
787-
StaticHeaderType newStaticHeaderType = StaticHeaderType.Factory.newInstance();
788-
newStaticHeaderType.setHostID(hostId);
789-
newStaticHeaderType.setNonce(nonce);
790-
newStaticHeaderType.setNumSegments(numSegments);
791-
newStaticHeaderType.setPartnerID(partnerId);
792-
newStaticHeaderType.setProduct(product);
793-
newStaticHeaderType.setSecurityMedium(securityMedium);
794-
newStaticHeaderType.setUserID(userId);
795-
newStaticHeaderType.setTimestamp(timestamp);
796-
newStaticHeaderType.setOrderDetails(orderDetails);
797-
newStaticHeaderType.setBankPubKeyDigests(bankPubKeyDigests);
792+
StaticHeaderType header = StaticHeaderType.Factory.newInstance();
793+
header.setHostID(hostId);
794+
header.setNonce(nonce);
795+
header.setNumSegments(numSegments);
796+
header.setPartnerID(partnerId);
797+
header.setProduct(product);
798+
header.setSecurityMedium(securityMedium);
799+
header.setUserID(userId);
800+
header.setTimestamp(timestamp);
801+
header.setOrderDetails(orderDetails);
802+
header.setBankPubKeyDigests(bankPubKeyDigests);
798803

799-
return newStaticHeaderType;
804+
return header;
800805
}
801806

802807
/**
@@ -881,17 +886,37 @@ public static StaticHeaderType createStaticHeaderType(String hostId, byte[] nonc
881886

882887
public static StaticHeaderOrderDetailsType createStaticHeaderOrderDetailsType(String orderId,
883888
StaticHeaderOrderDetailsType.AdminOrderType orderType,
884-
StandardOrderParamsType orderParams) {
889+
XmlObject orderParams, SchemaType orderParamsType) {
885890

886891
StaticHeaderOrderDetailsType type = StaticHeaderOrderDetailsType.Factory.newInstance();
887892
if (orderId != null) {
888893
type.setOrderID(orderId);
889894
}
890-
891-
type.setOrderParams(orderParams);
892-
var newInstance = StandardOrderParamsDocument.type.getDocumentElementName();
893-
qualifySubstitutionGroup(type.getOrderParams(), newInstance, null);
894895
type.setAdminOrderType(orderType);
896+
type.setOrderParams(orderParams);
897+
qualifySubstitutionGroup(type.getOrderParams(), orderParamsType.getDocumentElementName(), null);
898+
return type;
899+
}
900+
901+
public static BTUParamsType createBTUParams(String serviceName, String scope, String option,
902+
String messageName, String messageVersion, boolean signatureFlag) {
903+
var type = BTUParamsType.Factory.newInstance();
904+
var service = type.addNewService();
905+
service.setServiceName(serviceName);
906+
service.setScope(scope);
907+
if (option != null) {
908+
service.setServiceOption(option);
909+
}
910+
var msgType = MessageType.Factory.newInstance();
911+
912+
msgType.setStringValue(messageName);
913+
//msgType.setFormat(messageName);
914+
msgType.setVersion(messageVersion);
915+
service.setMsgName(msgType);
916+
if (signatureFlag) {
917+
var flag = type.addNewSignatureFlag();
918+
flag.setRequestEDS(true);
919+
}
895920
return type;
896921
}
897922

@@ -1134,10 +1159,16 @@ public static EbicsRequestDocument.EbicsRequest.Body createEbicsRequestBody(
11341159
* @return the <code>DataTransferRequestType</code> XML object
11351160
*/
11361161
public static DataTransferRequestType createDataTransferRequestType(
1137-
DataEncryptionInfo dataEncryptionInfo, SignatureData signatureData) {
1162+
DataEncryptionInfo dataEncryptionInfo, SignatureData signatureData, String digestValue) {
11381163
DataTransferRequestType newDataTransferRequestType = DataTransferRequestType.Factory.newInstance();
11391164
newDataTransferRequestType.setDataEncryptionInfo(dataEncryptionInfo);
11401165
newDataTransferRequestType.setSignatureData(signatureData);
1166+
if (digestValue != null) {
1167+
var digest = DataDigestType.Factory.newInstance();
1168+
digest.setSignatureVersion("A005");
1169+
digest.setStringValue(digestValue);
1170+
newDataTransferRequestType.setDataDigest(digest);
1171+
}
11411172

11421173
return newDataTransferRequestType;
11431174
}

src/main/java/org/kopi/ebics/xml/InitializationRequestElement.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ protected InitializationRequestElement(EbicsSession session,
6262
keySpec = new SecretKeySpec(key, "EAS");
6363
}
6464

65-
@Override
66-
public void build() throws EbicsException {
67-
SignedInfo signedInfo;
68-
69-
buildInitialization();
70-
signedInfo = new SignedInfo(session.getUser(), getDigest());
71-
signedInfo.build();
72-
((EbicsRequestDocument)document).getEbicsRequest().setAuthSignature(signedInfo.getSignatureType());
73-
((EbicsRequestDocument)document).getEbicsRequest().getAuthSignature().setSignatureValue(EbicsXmlFactory.createSignatureValueType(signedInfo.sign(toByteArray())));
74-
}
65+
@Override
66+
public void build() throws EbicsException {
67+
buildInitialization();
68+
SignedInfo signedInfo = new SignedInfo(session.getUser(), getDigest());
69+
signedInfo.build();
70+
var ebicsRequest = ((EbicsRequestDocument) document).getEbicsRequest();
71+
ebicsRequest.setAuthSignature(signedInfo.getSignatureType());
72+
ebicsRequest.getAuthSignature().setSignatureValue(
73+
EbicsXmlFactory.createSignatureValueType(signedInfo.sign(toByteArray())));
74+
}
7575

7676
@Override
7777
public String getName() {

0 commit comments

Comments
 (0)