Skip to content

Commit

Permalink
Merge pull request #5068 from BisonSchweizAG/bugfix/xmlprc5067
Browse files Browse the repository at this point in the history
Parameterise the XML-RPC parse method with the Media Type
  • Loading branch information
reinhapa authored Sep 25, 2023
2 parents d0b383d + 23c5a86 commit 31e79b5
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ private void store(final RemoteXMLResource res) throws XMLDBException {
} catch (final URISyntaxException e) {
throw new XMLDBException(ErrorCodes.INVALID_URI, e);
}
params.add(res.getMimeType());
params.add(1);
if (res.getCreationTime() != null) {
params.add(res.getCreationTime());
Expand Down
11 changes: 10 additions & 1 deletion exist-core/src/main/java/org/exist/xmlrpc/RpcAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -545,18 +545,27 @@ boolean parse(byte[] xmlData, String docName)
*
* @param xmlData The document data
* @param docName The path where the document will be stored
* @param mimeType the mimeType to check for
* @param overwrite Overwrite an existing document with the same path?
* @param created Specifies the creattion date
* @param modified Specifies the last modification date
* @return true, if the document is valid XML
* @throws EXistException If an internal error occurs
* @throws PermissionDeniedException If the current user is not allowed to perform this action
* @throws URISyntaxException If the URI contains syntax errors
*/
boolean parse(byte[] xmlData, String docName, int overwrite)
boolean parse(byte[] xmlData, String docName, String mimeType, int overwrite, Date created, Date modified)
throws EXistException, PermissionDeniedException, URISyntaxException;

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

boolean parse(byte[] xmlData, String docName, String mimeType, int overwrite)
throws EXistException, PermissionDeniedException, URISyntaxException;

boolean parse(byte[] xmlData, String docName, int overwrite)
throws EXistException, PermissionDeniedException, URISyntaxException;

boolean parse(String xml, String docName, int overwrite)
throws EXistException, PermissionDeniedException, URISyntaxException;

Expand Down
28 changes: 21 additions & 7 deletions exist-core/src/main/java/org/exist/xmlrpc/RpcConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -1336,18 +1336,24 @@ private boolean hasCollection(final XmldbURI collUri) throws EXistException, Per

@Override
public boolean parse(byte[] xml, String documentPath, int overwrite) throws URISyntaxException, EXistException, PermissionDeniedException {
return parse(xml, documentPath, overwrite, null, null);
return parse(xml, documentPath, null, overwrite, null, null);
}

@Override
public boolean parse(final byte[] xml, final String documentPath, final String mimeType, final int overwrite) throws URISyntaxException, EXistException, PermissionDeniedException {
return parse(xml, documentPath, mimeType, overwrite, null, null);
}

@Override
public boolean parse(final byte[] xml, final String documentPath,
final int overwrite, final Date created, final Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
return parse(xml, XmldbURI.xmldbUriFor(documentPath), overwrite, created, modified);
return parse(xml, documentPath, null, overwrite, created, modified);
}

private boolean parse(final byte[] xml, final XmldbURI docUri,
final int overwrite, @Nullable final Date created, @Nullable final Date modified) throws EXistException, PermissionDeniedException {

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

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

final long startTime = System.currentTimeMillis();

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

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

private MimeType lookupMimeType(@Nullable final String mimeType, final XmldbURI fileName) {
final MimeTable mimeTable = MimeTable.getInstance();
if (mimeType == null) {
return Optional.ofNullable(mimeTable.getContentTypeFor(fileName)).orElse(MimeType.BINARY_TYPE);
}
return Optional.ofNullable(mimeTable.getContentType(mimeType)).orElse(MimeType.BINARY_TYPE);
}

/**
* Parse a file previously uploaded with upload.
*
Expand Down Expand Up @@ -1492,7 +1506,7 @@ private boolean parseLocal(final String localFile, final XmldbURI docUri, final

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

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

Expand Down
101 changes: 101 additions & 0 deletions exist-core/src/test/java/org/exist/xmlrpc/MimeTypeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
* [email protected]
* http://www.exist-db.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.exist.xmlrpc;

import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.junit.Assert.assertEquals;

import org.exist.TestUtils;
import org.exist.test.ExistWebServer;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.xml.sax.SAXException;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.Resource;
import org.xmldb.api.base.ResourceType;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.CollectionManagementService;
import org.xmldb.api.modules.XMLResource;

public class MimeTypeTest {

@ClassRule
public final static ExistWebServer existWebServer = new ExistWebServer(true, false, true, true);

private final static String COLLECTION_NAME = "rpctest";
private static final String DOCUMENT_NAME = "myxmldoc";
private final static String XML_CONTENT = """
<xml><it><is>
</is></it></xml>
""";

private static String getBaseUri() {
return "xmldb:exist://localhost:" + existWebServer.getPort() + "/xmlrpc";
}

@Test
public void testXMLMimeType() throws XMLDBException {
// store an XML document without an .xml extension
try(Collection collection = DatabaseManager.getCollection(getBaseUri() + "/db/" + COLLECTION_NAME, TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD)){
final Class<? extends Resource> xmlResourceType = XMLResource.class;
final XMLResource resource = (XMLResource)collection.createResource(DOCUMENT_NAME, xmlResourceType);
resource.setContent(XML_CONTENT);
collection.storeResource(resource);
assertEquals(ResourceType.XML_RESOURCE, resource.getResourceType());
}

// retrieve the document and verify its resource type
try(Collection collection = DatabaseManager.getCollection(getBaseUri() + "/db/" + COLLECTION_NAME, TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD)){
Resource resource = collection.getResource(DOCUMENT_NAME);
assertEquals(ResourceType.XML_RESOURCE, resource.getResourceType());
}
}

@BeforeClass
public static void startServer() throws ClassNotFoundException, IllegalAccessException, InstantiationException, XMLDBException, SAXException {
// initialize XML:DB driver
Class<?> cl = Class.forName("org.exist.xmldb.DatabaseImpl");
Database database = (Database) cl.newInstance();
DatabaseManager.registerDatabase(database);

Collection root = DatabaseManager.getCollection(getBaseUri() + "/db", TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD);

CollectionManagementService mgmt = root.getService(CollectionManagementService.class);
assertThatNoException().isThrownBy(() -> mgmt.createCollection(COLLECTION_NAME));
}

@AfterClass
public static void stopServer() throws XMLDBException {
Collection root = DatabaseManager.getCollection(getBaseUri() + "/db", TestUtils.ADMIN_DB_USER, TestUtils.ADMIN_DB_PWD);
CollectionManagementService mgmt =
root.getService(CollectionManagementService.class);
mgmt.removeCollection(COLLECTION_NAME);

Collection config = DatabaseManager.getCollection(getBaseUri() + "/db/system/config/db", "admin", "");
mgmt = config.getService(CollectionManagementService.class);
mgmt.removeCollection(COLLECTION_NAME);
}
}

0 comments on commit 31e79b5

Please sign in to comment.