Skip to content

Commit

Permalink
pcorlessGH-46 Adds Webdav support
Browse files Browse the repository at this point in the history
  • Loading branch information
gtache committed Feb 13, 2020
1 parent a5266d7 commit c8dc580
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 18 deletions.
12 changes: 7 additions & 5 deletions viewer/viewer-awt/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ applicationDefaultJvmArgs = ["-Xms64m", "-Xmx1024m"]

def sectionName = 'org/icepdf/ri/'
def baseJarName = 'icepdf'
def baseAppendixName = 'viewer'
def baseAppendixName = 'viewer'

// generatePomFileForViewerJarPublication
publishing {
Expand Down Expand Up @@ -48,20 +48,20 @@ jar {

doFirst {
manifest {
attributes ('Created-By': System.getProperty('java.version') + ' (' + System.getProperty('java.vendor') + ')')
attributes('Created-By': System.getProperty('java.version') + ' (' + System.getProperty('java.vendor') + ')')
// executable jar
attributes("Main-Class": 'org.icepdf.ri.viewer.Main')
if (!configurations.runtime.isEmpty()) {
attributes('Class-Path':
configurations.runtime.collect{it.name}.join(' '))
configurations.runtime.collect { it.name }.join(' '))
}
}
}

manifest {
// section names attributes
attributes("Implementation-Title": "${baseName + '-' + appendix}", "${sectionName}")
attributes("Implementation-Version": "${VERSION + (RELEASE_TYPE?.trim()? '-' + RELEASE_TYPE:'')}", "${sectionName}")
attributes("Implementation-Version": "${VERSION + (RELEASE_TYPE?.trim() ? '-' + RELEASE_TYPE : '')}", "${sectionName}")
attributes("Implementation-Vendor": "${COMPANY}", "${sectionName}")
}
}
Expand All @@ -75,7 +75,7 @@ task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
manifest {
attributes("Implementation-Title": "${baseName + '-' + appendix}", "${sectionName}")
attributes("Implementation-Version": "${VERSION + (RELEASE_TYPE?.trim()? '-' + RELEASE_TYPE:'')}", "${sectionName}")
attributes("Implementation-Version": "${VERSION + (RELEASE_TYPE?.trim() ? '-' + RELEASE_TYPE : '')}", "${sectionName}")
attributes("Implementation-Vendor": "${COMPANY}", "${sectionName}")
}
from sourceSets.main.allSource
Expand All @@ -98,4 +98,6 @@ artifacts {

dependencies {
compile project(':core:core-awt')
compile 'com.github.lookfirst:sardine:5.9'
compile 'org.apache.tika:tika-core:1.23'
}
13 changes: 13 additions & 0 deletions viewer/viewer-awt/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,17 @@
</plugins>
</build>

<dependencies>
<dependency>
<groupId>com.github.lookfirst</groupId>
<artifactId>sardine</artifactId>
<version>5.9</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.23</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.icepdf.ri.common;

import com.github.sardine.impl.SardineException;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.stage.FileChooser;
Expand Down Expand Up @@ -52,10 +53,7 @@
import org.icepdf.ri.common.views.annotations.AnnotationState;
import org.icepdf.ri.common.views.annotations.summary.AnnotationSummaryFrame;
import org.icepdf.ri.common.views.destinations.DestinationComponent;
import org.icepdf.ri.util.BareBonesBrowserLaunch;
import org.icepdf.ri.util.ViewerPropertiesManager;
import org.icepdf.ri.util.TextExtractionTask;
import org.icepdf.ri.util.URLAccess;
import org.icepdf.ri.util.*;
import org.icepdf.ri.viewer.WindowManager;

import javax.print.attribute.PrintRequestAttributeSet;
Expand Down Expand Up @@ -273,7 +271,7 @@ public class SwingController extends ComponentAdapter
// sub controller for document text searching.
protected DocumentSearchController documentSearchController;


private DavFileClient pdfClient;
protected Document document;
protected boolean disposed;

Expand Down Expand Up @@ -2732,6 +2730,62 @@ protected Object doInBackground() throws Exception {
}
}

/**
* Opens a document specified by the DavFileClient. Asks the user their password if needed
* @param davClient The client
*/
public void openDocument(final DavFileClient davClient) {
pdfClient = davClient;
JPanel panel = new JPanel();
if (pdfClient.getPassword() == null) {
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JLabel label = new JLabel(MessageFormat.format(messageBundle.getString("viewer.dialog.dav.password.label"), pdfClient.getName()));
JPasswordField field = new JPasswordField();
panel.add(label);
panel.add(field);
String[] options = {messageBundle.getString("viewer.dialog.dav.password.button.ok"), messageBundle.getString("viewer.dialog.dav.password.button.cancel")};
int option = JOptionPane.showOptionDialog(getViewerFrame(), panel, messageBundle.getString("viewer.dialog.dav.password.title"),
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if (option == JOptionPane.OK_OPTION) {
pdfClient.setPassword(new String(field.getPassword()));
} else if (option == JOptionPane.CANCEL_OPTION) {
return;
}
}
try {
InputStream stream = pdfClient.getStream();
document = new Document();
document.setInputStream(new BufferedInputStream(stream), pdfClient.getUrl());
commonNewDocumentHandling(pdfClient.getUrl());
} catch (SardineException e) {
SwingUtilities.invokeLater(() -> {
org.icepdf.ri.util.Resources.showMessageDialog(
viewer,
JOptionPane.INFORMATION_MESSAGE,
messageBundle,
"viewer.dialog.sardine.exception.title",
"viewer.dialog.sardine.exception.msg",
e.getMessage() != null ? e.getMessage() : e.toString());
//401 is probably wrong password
if (e.getStatusCode() == 401) {
openDocument(davClient);
}
});
} catch (IOException | PDFException | PDFSecurityException e) {
SwingUtilities.invokeLater(() -> org.icepdf.ri.util.Resources.showMessageDialog(
viewer,
JOptionPane.INFORMATION_MESSAGE,
messageBundle,
"viewer.dialog.dav.exception.title",
"viewer.dialog.dav.exception.msg",
e.getMessage() != null ? e.getMessage() : e.toString()));
} finally {
setDisplayTool(DocumentViewModelImpl.DISPLAY_TOOL_PAN);
}
}


/**
* Opens a Document via the specified InputStream. This method is a convenience method provided for
* backwards compatibility.
Expand Down Expand Up @@ -3129,7 +3183,9 @@ public void commonNewDocumentHandling(String fileDescription) {

// add to the main pdfContentPanel the document peer
if (viewer != null) {
Object[] messageArguments = new Object[]{fileDescription};
final File f = new File(fileDescription);
final String argument = pdfClient == null ? (f.exists() ? f.getName() : fileDescription) : pdfClient.getName();
Object[] messageArguments = {argument};
MessageFormat formatter = new MessageFormat(
messageBundle.getString("viewer.window.title.open.default"));
viewer.setTitle(formatter.format(messageArguments));
Expand Down Expand Up @@ -3439,6 +3495,22 @@ public void saveFile() {
messageBundle,
"viewer.dialog.saveAs.noUpdates.title",
"viewer.dialog.saveAs.noUpdates.msg");
} else if (pdfClient != null) {
try {
//TODO no choice but to dump file to append changes as long as IncrementalUpdater is obfuscated
File tmp = Files.createTempFile(pdfClient.getName(), "." + FileExtensionUtils.pdf).toFile();
try (final OutputStream out = new BufferedOutputStream(new FileOutputStream(tmp))) {
document.saveToOutputStream(out);
}
try (final InputStream pdfIn = new BufferedInputStream(new FileInputStream(tmp))) {
pdfClient.save(pdfIn);
}
tmp.delete();
savedChanges = document.getStateManager().getChanges();
} catch (IOException e) {
logger.log(Level.FINE, "IOException while saving dav", e);
saveFileAs();
}
} else {
if (saveFilePath != null && !saveFilePath.isEmpty()) {
File out = new File(saveFilePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.icepdf.ri.common;

import org.icepdf.ri.common.views.Controller;
import org.icepdf.ri.util.DavFileClient;
import org.icepdf.ri.util.ViewerPropertiesManager;

import javax.swing.*;
Expand All @@ -37,6 +38,8 @@ public interface WindowManagementCallback {

void newWindow(URL url);

void newWindow(DavFileClient fileClient);

void disposeWindow(Controller controller, JFrame viewer, Preferences preferences);

void minimiseAllWindows();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.icepdf.ri.common.ViewModel;
import org.icepdf.ri.common.WindowManagementCallback;
import org.icepdf.ri.common.utility.outline.OutlineItemTreeNode;
import org.icepdf.ri.util.DavFileClient;
import org.icepdf.ri.util.ViewerPropertiesManager;

import java.awt.*;
Expand Down Expand Up @@ -237,6 +238,13 @@ public interface Controller extends PropertyChangeListener {
*/
void openDocument(final URL location);

/**
* Opens a document specified by the given DavFileClient
*
* @param davFileClient The dav file client
*/
void openDocument(DavFileClient davFileClient);

/**
* Load the specified file in a new Viewer RI window.
*
Expand Down
139 changes: 139 additions & 0 deletions viewer/viewer-awt/src/main/java/org/icepdf/ri/util/DavFileClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.icepdf.ri.util;

import com.github.sardine.DavResource;
import com.github.sardine.Sardine;
import com.github.sardine.SardineFactory;
import org.apache.tika.Tika;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DavFileClient {

private final Sardine sardine;
private final String url;
private final String username;
private final String folderUrl;
private final String name;
private final String ext;
private final boolean readOnly;
private String password;
private int revision = 0;
private File file;
private InputStream stream;
private String mimeType;

public DavFileClient(final String url) {
this(url, null, null);
}

public DavFileClient(final String url, final String username, final String password) {
this(url, username, password, false);
}

public DavFileClient(final String url, final String username, final String password, final boolean readOnly) {
this.url = url;
this.username = username;
this.password = password;
this.sardine = username == null || password == null ? SardineFactory.begin() : SardineFactory.begin(username, password);
final String[] split = url.split("/");
folderUrl = Arrays.stream(split).limit(split.length - 1).collect(Collectors.joining("/"));
final String[] names = split[split.length - 1].split("\\.");
name = names[0];
ext = names[1];
this.readOnly = readOnly;
}

public List<DavResource> getFolderContents() throws IOException {
return sardine.list(folderUrl);
}

public File getFile() throws IOException {
if (file == null) {
file = File.createTempFile(name, "." + ext);
try (final InputStream stream = sardine.get(url)) {
Files.copy(stream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
mimeType = new Tika().detect(file);
}
}
return file;
}

public InputStream getStream() throws IOException {
if (stream == null || stream.available() == 0) {
this.stream = sardine.get(url);
}
return stream;
}

public void save(final InputStream inputStream) throws IOException {
if (!readOnly) {
if (inputStream.markSupported()) {
mimeType = new Tika().detect(stream);
}
if (mimeType == null || mimeType.equals("application/octet-stream")) {
mimeType = new Tika().detect(name + "." + ext);
}
final String newUrl = folderUrl + "/" + name + "." + ext;
sardine.put(newUrl, inputStream, mimeType);
revision += 1;
}
}

public void delete() throws IOException {
if (!readOnly) {
sardine.delete(url);
}
}

public boolean exists() throws IOException {
return sardine.exists(url);
}

public String getName() {
return name;
}

public String getExt() {
return ext;
}

public int getRevision() {
return revision;
}

public String getMimeType() {
return mimeType;
}

public String getFolderUrl() {
return folderUrl;
}

public String getUrl() {
return url;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public void setPassword(final String password) {
this.password = password;
sardine.setCredentials(username, password);
}

public boolean isReadOnly() {
return readOnly;
}
}
Loading

0 comments on commit c8dc580

Please sign in to comment.