Skip to content

Commit 23c5a86

Browse files
ohumbelreinhapa
authored andcommitted
[feature] Provide mime type on store XMLResource
The mime type that is available on the remote resource was not provided when calling the parse() procedure on the backend and has now been added. When calculating the mime type being stored the following order will be used: - mime type as given by the method call - mime type caclulated based on the file name extension - default mime type 'application/octet-stream' is used Co-authored-by: Otmar Humbel <[email protected]> Signed-off-by: Patrick Reinhart <[email protected]>
1 parent 504604c commit 23c5a86

File tree

4 files changed

+133
-8
lines changed

4 files changed

+133
-8
lines changed

exist-core/src/main/java/org/exist/xmldb/RemoteCollection.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ private void store(final RemoteXMLResource res) throws XMLDBException {
519519
} catch (final URISyntaxException e) {
520520
throw new XMLDBException(ErrorCodes.INVALID_URI, e);
521521
}
522+
params.add(res.getMimeType());
522523
params.add(1);
523524
if (res.getCreationTime() != null) {
524525
params.add(res.getCreationTime());

exist-core/src/main/java/org/exist/xmlrpc/RpcAPI.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,18 +545,27 @@ boolean parse(byte[] xmlData, String docName)
545545
*
546546
* @param xmlData The document data
547547
* @param docName The path where the document will be stored
548+
* @param mimeType the mimeType to check for
548549
* @param overwrite Overwrite an existing document with the same path?
550+
* @param created Specifies the creattion date
551+
* @param modified Specifies the last modification date
549552
* @return true, if the document is valid XML
550553
* @throws EXistException If an internal error occurs
551554
* @throws PermissionDeniedException If the current user is not allowed to perform this action
552555
* @throws URISyntaxException If the URI contains syntax errors
553556
*/
554-
boolean parse(byte[] xmlData, String docName, int overwrite)
557+
boolean parse(byte[] xmlData, String docName, String mimeType, int overwrite, Date created, Date modified)
555558
throws EXistException, PermissionDeniedException, URISyntaxException;
556559

557560
boolean parse(byte[] xmlData, String docName, int overwrite, Date created, Date modified)
558561
throws EXistException, PermissionDeniedException, URISyntaxException;
559562

563+
boolean parse(byte[] xmlData, String docName, String mimeType, int overwrite)
564+
throws EXistException, PermissionDeniedException, URISyntaxException;
565+
566+
boolean parse(byte[] xmlData, String docName, int overwrite)
567+
throws EXistException, PermissionDeniedException, URISyntaxException;
568+
560569
boolean parse(String xml, String docName, int overwrite)
561570
throws EXistException, PermissionDeniedException, URISyntaxException;
562571

exist-core/src/main/java/org/exist/xmlrpc/RpcConnection.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,18 +1336,24 @@ private boolean hasCollection(final XmldbURI collUri) throws EXistException, Per
13361336

13371337
@Override
13381338
public boolean parse(byte[] xml, String documentPath, int overwrite) throws URISyntaxException, EXistException, PermissionDeniedException {
1339-
return parse(xml, documentPath, overwrite, null, null);
1339+
return parse(xml, documentPath, null, overwrite, null, null);
1340+
}
1341+
1342+
@Override
1343+
public boolean parse(final byte[] xml, final String documentPath, final String mimeType, final int overwrite) throws URISyntaxException, EXistException, PermissionDeniedException {
1344+
return parse(xml, documentPath, mimeType, overwrite, null, null);
13401345
}
13411346

13421347
@Override
13431348
public boolean parse(final byte[] xml, final String documentPath,
13441349
final int overwrite, final Date created, final Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
1345-
return parse(xml, XmldbURI.xmldbUriFor(documentPath), overwrite, created, modified);
1350+
return parse(xml, documentPath, null, overwrite, created, modified);
13461351
}
13471352

1348-
private boolean parse(final byte[] xml, final XmldbURI docUri,
1349-
final int overwrite, @Nullable final Date created, @Nullable final Date modified) throws EXistException, PermissionDeniedException {
1350-
1353+
@Override
1354+
public boolean parse(final byte[] xml, final String documentPath, @Nullable String mimeType,
1355+
final int overwrite, @Nullable final Date created, @Nullable final Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
1356+
final XmldbURI docUri = XmldbURI.xmldbUriFor(documentPath);
13511357
return this.<Boolean>writeCollection(docUri.removeLastSegment()).apply((collection, broker, transaction) -> {
13521358

13531359
try(final ManagedDocumentLock lockedDocument = broker.getBrokerPool().getLockManager().acquireDocumentWriteLock(docUri)) {
@@ -1366,7 +1372,7 @@ private boolean parse(final byte[] xml, final XmldbURI docUri,
13661372

13671373
final long startTime = System.currentTimeMillis();
13681374

1369-
final MimeType mime = MimeTable.getInstance().getContentTypeFor(docUri.lastSegment());
1375+
final MimeType mime = lookupMimeType(mimeType, docUri.lastSegment());
13701376
broker.storeDocument(transaction, docUri.lastSegment(), source, mime, created, modified, null, null, null, collection);
13711377

13721378
// NOTE: early release of Collection lock inline with Asymmetrical Locking scheme
@@ -1379,6 +1385,14 @@ private boolean parse(final byte[] xml, final XmldbURI docUri,
13791385
});
13801386
}
13811387

1388+
private MimeType lookupMimeType(@Nullable final String mimeType, final XmldbURI fileName) {
1389+
final MimeTable mimeTable = MimeTable.getInstance();
1390+
if (mimeType == null) {
1391+
return Optional.ofNullable(mimeTable.getContentTypeFor(fileName)).orElse(MimeType.BINARY_TYPE);
1392+
}
1393+
return Optional.ofNullable(mimeTable.getContentType(mimeType)).orElse(MimeType.BINARY_TYPE);
1394+
}
1395+
13821396
/**
13831397
* Parse a file previously uploaded with upload.
13841398
*
@@ -1492,7 +1506,7 @@ private boolean parseLocal(final String localFile, final XmldbURI docUri, final
14921506

14931507
// parse the source
14941508
try (final FileInputSource source = sourceSupplier.get()) {
1495-
final MimeType mime = Optional.ofNullable(MimeTable.getInstance().getContentType(mimeType)).orElse(MimeType.BINARY_TYPE);
1509+
final MimeType mime = lookupMimeType(mimeType, docUri.lastSegment());
14961510

14971511
broker.storeDocument(transaction, docUri.lastSegment(), source, mime, created, modified, null, null, null, collection);
14981512

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
package org.exist.xmlrpc;
23+
24+
import static org.assertj.core.api.Assertions.assertThatNoException;
25+
import static org.junit.Assert.assertEquals;
26+
27+
import org.exist.TestUtils;
28+
import org.exist.test.ExistWebServer;
29+
import org.junit.AfterClass;
30+
import org.junit.BeforeClass;
31+
import org.junit.ClassRule;
32+
import org.junit.Test;
33+
import org.xml.sax.SAXException;
34+
import org.xmldb.api.DatabaseManager;
35+
import org.xmldb.api.base.Collection;
36+
import org.xmldb.api.base.Database;
37+
import org.xmldb.api.base.Resource;
38+
import org.xmldb.api.base.ResourceType;
39+
import org.xmldb.api.base.XMLDBException;
40+
import org.xmldb.api.modules.CollectionManagementService;
41+
import org.xmldb.api.modules.XMLResource;
42+
43+
public class MimeTypeTest {
44+
45+
@ClassRule
46+
public final static ExistWebServer existWebServer = new ExistWebServer(true, false, true, true);
47+
48+
private final static String COLLECTION_NAME = "rpctest";
49+
private static final String DOCUMENT_NAME = "myxmldoc";
50+
private final static String XML_CONTENT = """
51+
<xml><it><is>
52+
</is></it></xml>
53+
""";
54+
55+
private static String getBaseUri() {
56+
return "xmldb:exist://localhost:" + existWebServer.getPort() + "/xmlrpc";
57+
}
58+
59+
@Test
60+
public void testXMLMimeType() throws XMLDBException {
61+
// store an XML document without an .xml extension
62+
try(Collection collection = DatabaseManager.getCollection(getBaseUri() + "/db/" + COLLECTION_NAME, TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD)){
63+
final Class<? extends Resource> xmlResourceType = XMLResource.class;
64+
final XMLResource resource = (XMLResource)collection.createResource(DOCUMENT_NAME, xmlResourceType);
65+
resource.setContent(XML_CONTENT);
66+
collection.storeResource(resource);
67+
assertEquals(ResourceType.XML_RESOURCE, resource.getResourceType());
68+
}
69+
70+
// retrieve the document and verify its resource type
71+
try(Collection collection = DatabaseManager.getCollection(getBaseUri() + "/db/" + COLLECTION_NAME, TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD)){
72+
Resource resource = collection.getResource(DOCUMENT_NAME);
73+
assertEquals(ResourceType.XML_RESOURCE, resource.getResourceType());
74+
}
75+
}
76+
77+
@BeforeClass
78+
public static void startServer() throws ClassNotFoundException, IllegalAccessException, InstantiationException, XMLDBException, SAXException {
79+
// initialize XML:DB driver
80+
Class<?> cl = Class.forName("org.exist.xmldb.DatabaseImpl");
81+
Database database = (Database) cl.newInstance();
82+
DatabaseManager.registerDatabase(database);
83+
84+
Collection root = DatabaseManager.getCollection(getBaseUri() + "/db", TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD);
85+
86+
CollectionManagementService mgmt = root.getService(CollectionManagementService.class);
87+
assertThatNoException().isThrownBy(() -> mgmt.createCollection(COLLECTION_NAME));
88+
}
89+
90+
@AfterClass
91+
public static void stopServer() throws XMLDBException {
92+
Collection root = DatabaseManager.getCollection(getBaseUri() + "/db", TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD);
93+
CollectionManagementService mgmt =
94+
root.getService(CollectionManagementService.class);
95+
mgmt.removeCollection(COLLECTION_NAME);
96+
97+
Collection config = DatabaseManager.getCollection(getBaseUri() + "/db/system/config/db", "admin", "");
98+
mgmt = config.getService(CollectionManagementService.class);
99+
mgmt.removeCollection(COLLECTION_NAME);
100+
}
101+
}

0 commit comments

Comments
 (0)