
org.apache.chemistry.opencmis.workbench.ClientHelper Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.chemistry.opencmis.workbench;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Properties;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JRootPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.DefaultEditorKit;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.ObjectId;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.apache.chemistry.opencmis.commons.impl.IOUtils;
import org.apache.chemistry.opencmis.workbench.swing.WorkbenchFileChooser;
import org.apache.chemistry.opencmis.workbench.worker.OpenContentWorker;
import org.apache.chemistry.opencmis.workbench.worker.StoreWorker;
import org.apache.chemistry.opencmis.workbench.worker.TempFileContentWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ClientHelper {
public static final Color LINK_COLOR = new Color(105, 29, 21);
public static final Color LINK_SELECTED_COLOR = new Color(255, 255, 255);
public static final int TOOLBAR_ICON_SIZE = 20;
public static final int BUTTON_ICON_SIZE = 11;
public static final int OBJECT_ICON_SIZE = 16;
public static final int ICON_BUTTON_ICON_SIZE = 16;
public static final String UNDO_ACTION_KEY = "Undo";
public static final String REDO_ACTION_KEY = "Redo";
private static final Logger LOG = LoggerFactory.getLogger(ClientHelper.class);
private static final ImageIcon CMIS_ICON = getIcon("icon256.png");
private static final List CMIS_ICON_LIST = new ArrayList();
static {
try {
CMIS_ICON_LIST.add(ImageIO.read(ClientHelper.class.getResource("/images/icon256.png")));
CMIS_ICON_LIST.add(ImageIO.read(ClientHelper.class.getResource("/images/icon128.png")));
CMIS_ICON_LIST.add(ImageIO.read(ClientHelper.class.getResource("/images/icon64.png")));
CMIS_ICON_LIST.add(ImageIO.read(ClientHelper.class.getResource("/images/icon48.png")));
CMIS_ICON_LIST.add(ImageIO.read(ClientHelper.class.getResource("/images/icon32.png")));
CMIS_ICON_LIST.add(ImageIO.read(ClientHelper.class.getResource("/images/icon16.png")));
} catch (Exception e) {
LOG.error("Icons cannot be loaded!", e);
}
}
private ClientHelper() {
}
public static void logError(Throwable t) {
if (LOG.isErrorEnabled()) {
LOG.error(t.getClass().getSimpleName() + ": " + t.getMessage(), t);
if (t instanceof CmisBaseException) {
CmisBaseException cex = (CmisBaseException) t;
if (cex.getCode() != null) {
LOG.error("Error code: " + cex.getCode());
}
if (cex.getErrorContent() != null) {
LOG.error("Error content: " + cex.getErrorContent());
}
if (LOG.isDebugEnabled() && cex.getCause() != null) {
LOG.debug("Cause: " + cex.getCause().toString(), cex.getCause());
}
}
}
}
public static void showError(Component parent, Throwable t) {
logError(t);
if (parent == null) {
new ExceptionDialog((Frame) null, t);
} else {
Window window = (Window) SwingUtilities.getRoot(parent);
if (window instanceof Frame) {
new ExceptionDialog((Frame) window, t);
} else if (window instanceof Dialog) {
new ExceptionDialog((Dialog) window, t);
} else {
new ExceptionDialog((Frame) null, t);
}
}
}
public static boolean isMacOSX() {
String osname = System.getProperty("os.name");
return osname == null ? false : osname.startsWith("Mac OS X");
}
public static void installKeyBindings() {
if (isMacOSX()) {
final KeyStroke copyKeyStroke = KeyStroke.getKeyStroke("meta pressed C");
final KeyStroke pasteKeyStroke = KeyStroke.getKeyStroke("meta pressed V");
final KeyStroke cutKeyStroke = KeyStroke.getKeyStroke("meta pressed X");
final KeyStroke allKeyStroke = KeyStroke.getKeyStroke("meta pressed A");
InputMap textFieldMap = (InputMap) UIManager.get("TextField.focusInputMap");
textFieldMap.put(copyKeyStroke, DefaultEditorKit.copyAction);
textFieldMap.put(pasteKeyStroke, DefaultEditorKit.pasteAction);
textFieldMap.put(cutKeyStroke, DefaultEditorKit.cutAction);
textFieldMap.put(allKeyStroke, DefaultEditorKit.selectAllAction);
InputMap formattedTextFieldMap = (InputMap) UIManager.get("FormattedTextField.focusInputMap");
formattedTextFieldMap.put(copyKeyStroke, DefaultEditorKit.copyAction);
formattedTextFieldMap.put(pasteKeyStroke, DefaultEditorKit.pasteAction);
formattedTextFieldMap.put(cutKeyStroke, DefaultEditorKit.cutAction);
formattedTextFieldMap.put(allKeyStroke, DefaultEditorKit.selectAllAction);
InputMap textAreaMap = (InputMap) UIManager.get("TextArea.focusInputMap");
textAreaMap.put(copyKeyStroke, DefaultEditorKit.copyAction);
textAreaMap.put(pasteKeyStroke, DefaultEditorKit.pasteAction);
textAreaMap.put(cutKeyStroke, DefaultEditorKit.cutAction);
textAreaMap.put(allKeyStroke, DefaultEditorKit.selectAllAction);
InputMap editorPaneMap = (InputMap) UIManager.get("EditorPane.focusInputMap");
editorPaneMap.put(copyKeyStroke, DefaultEditorKit.copyAction);
editorPaneMap.put(pasteKeyStroke, DefaultEditorKit.pasteAction);
editorPaneMap.put(cutKeyStroke, DefaultEditorKit.cutAction);
editorPaneMap.put(allKeyStroke, DefaultEditorKit.selectAllAction);
InputMap passwordFieldMap = (InputMap) UIManager.get("PasswordField.focusInputMap");
passwordFieldMap.put(pasteKeyStroke, DefaultEditorKit.pasteAction);
}
}
public static void installEscapeBinding(final Window window, final JRootPane rootPane, final boolean dispose) {
final KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE");
final InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(stroke, "ESCAPE");
rootPane.getActionMap().put("ESCAPE", new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (dispose) {
window.dispose();
} else {
window.setVisible(false);
}
}
});
}
public static AbstractAction createAndAttachUndoAction(final UndoManager undoManager, JComponent component) {
AbstractAction undoAction = new AbstractAction(UNDO_ACTION_KEY) {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent evt) {
try {
if (undoManager.canUndo()) {
undoManager.undo();
}
} catch (CannotUndoException e) {
}
}
};
component.getActionMap().put(UNDO_ACTION_KEY, undoAction);
KeyStroke undoKey = isMacOSX() ? KeyStroke.getKeyStroke("meta pressed Z")
: KeyStroke.getKeyStroke("control pressed Z");
component.getInputMap().put(undoKey, UNDO_ACTION_KEY);
return undoAction;
}
public static AbstractAction createAndAttachRedoAction(final UndoManager undoManager, JComponent component) {
AbstractAction redoAction = new AbstractAction(REDO_ACTION_KEY) {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent evt) {
try {
if (undoManager.canRedo()) {
undoManager.redo();
}
} catch (CannotUndoException e) {
}
}
};
component.getActionMap().put(REDO_ACTION_KEY, redoAction);
KeyStroke redoKey = isMacOSX() ? KeyStroke.getKeyStroke("meta shift pressed Z")
: KeyStroke.getKeyStroke("control shift pressed Z");
component.getInputMap().put(redoKey, REDO_ACTION_KEY);
return redoAction;
}
public static ImageIcon getIcon(String name) {
URL imageURL = ClientHelper.class.getResource("/images/" + name);
if (imageURL != null) {
return WorkbenchScale.scaleIcon(new ImageIcon(imageURL));
}
return null;
}
public static ImageIcon getCmisIconImage() {
return CMIS_ICON;
}
public static List extends Image> getCmisIconImages() {
return CMIS_ICON_LIST;
}
public static String getDateString(GregorianCalendar cal) {
if (cal == null) {
return "";
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZ");
sdf.setTimeZone(cal.getTimeZone());
return sdf.format(cal.getTime());
}
public static void download(Component component, CmisObject object, String streamId) {
OpenContentWorker worker = new OpenContentWorker(null, object, streamId) {
@Override
protected void processStream(Component comp, ContentStream contentStream, String filename) {
WorkbenchFileChooser fileChooser = new WorkbenchFileChooser();
fileChooser.setSelectedFile(new File(filename));
int chooseResult = fileChooser.showDialog(comp, "Download");
if (chooseResult == WorkbenchFileChooser.APPROVE_OPTION) {
(new StoreWorker(contentStream, fileChooser.getSelectedFile(), filename)).executeTask();
} else {
IOUtils.closeQuietly(contentStream);
}
}
};
worker.executeTask();
}
public static void open(Component component, CmisObject object, String streamId) {
if (!Desktop.isDesktopSupported()) {
download(component, object, streamId);
return;
}
final Desktop desktop = Desktop.getDesktop();
if (!desktop.isSupported(Desktop.Action.OPEN)) {
download(component, object, streamId);
return;
}
TempFileContentWorker worker = new TempFileContentWorker(component, object, streamId) {
@Override
protected void processTempFile(File file) {
try {
desktop.open(file);
} catch (Exception e) {
if (e instanceof IOException) {
copy(file);
} else {
showError(e);
}
}
}
private void copy(File file) {
WorkbenchFileChooser fileChooser = new WorkbenchFileChooser();
fileChooser.setSelectedFile(new File(file.getName()));
int chooseResult = fileChooser.showDialog(getComponent(), "Download");
if (chooseResult == WorkbenchFileChooser.APPROVE_OPTION
&& !file.equals(fileChooser.getSelectedFile())) {
try {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(file);
out = new FileOutputStream(fileChooser.getSelectedFile());
IOUtils.copy(in, out, 64 * 1024);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
} catch (Exception e) {
showError(e);
}
}
}
};
worker.executeTask();
}
public static File createTempFile(String filename) {
String tempDir = System.getProperty("java.io.tmpdir");
File clientTempDir = new File(tempDir, "cmisworkbench");
if (!clientTempDir.exists() && !clientTempDir.mkdirs()) {
throw new CmisRuntimeException("Could not create directory for temp file!");
}
clientTempDir.deleteOnExit();
File tempFile = new File(clientTempDir, filename);
tempFile.deleteOnExit();
return tempFile;
}
public static void copyTableToClipboard(JTable table, boolean onlySelected) {
final String newline = System.getProperty("line.separator");
final StringBuilder sb = new StringBuilder(1024);
final int rows = table.getModel().getRowCount();
final int cols = table.getModel().getColumnCount();
for (int col = 0; col < cols; col++) {
if (col > 0) {
sb.append(',');
}
sb.append(formatCSVValue(table.getModel().getColumnName(col)));
}
sb.append(newline);
int[] seletedRows = table.getSelectedRows();
Arrays.sort(seletedRows);
for (int row = 0; row < rows; row++) {
if (onlySelected) {
if (Arrays.binarySearch(seletedRows, row) < 0) {
continue;
}
}
for (int col = 0; col < cols; col++) {
if (col > 0) {
sb.append(',');
}
Object value = table.getModel().getValueAt(row, col);
sb.append(formatCSVValue(value));
}
sb.append(newline);
}
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable transferable = new StringSelection(sb.toString());
clipboard.setContents(transferable, null);
}
public static String encodeHtml(StringBuilder sb, String s) {
if (s == null) {
return "";
}
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '<') {
sb.append("<");
} else if (c == '>') {
sb.append(">");
} else if (c == '"') {
sb.append(""");
} else if (c == '\'') {
sb.append("'");
} else if (c > 127) {
sb.append("" + (int) c + ";");
} else {
sb.append(c);
}
}
return sb.toString();
}
private static String formatCSVValue(Object value) {
if (value == null) {
return "";
} else if (value instanceof GregorianCalendar) {
return getDateString((GregorianCalendar) value);
} else if (value instanceof String) {
String s = value.toString();
StringBuilder sb = new StringBuilder(s.length() + 16);
sb.append('\"');
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
sb.append(c);
if (c == '\"') {
sb.append('\"');
}
}
sb.append('\"');
return sb.toString();
} else if (value instanceof Collection>) {
StringBuilder sb = new StringBuilder(((Collection>) value).size() * 16 + 16);
sb.append('[');
for (Object v : (Collection>) value) {
if (sb.length() > 1) {
sb.append(',');
}
sb.append(formatCSVValue(v));
}
sb.append(']');
return sb.toString();
} else if (value instanceof ObjectId) {
return formatCSVValue(((ObjectId) value).getId());
} else if (value instanceof Icon) {
return "";
}
return value.toString();
}
public static URI getClasspathURI(String path) {
try {
return ClientHelper.class.getResource(path).toURI();
} catch (URISyntaxException e) {
// not very likely
LOG.error(e.getMessage(), e);
return null;
}
}
public static String readFileAndRemoveHeader(final URI file) {
if (file == null) {
return "";
}
final InputStream stream;
try {
stream = file.toURL().openStream();
} catch (Exception e) {
return "";
}
final String result = readStreamAndRemoveHeader(stream);
IOUtils.closeQuietly(stream);
return result;
}
public static String readStreamAndRemoveHeader(final InputStream stream) {
if (stream == null) {
return "";
}
try {
return IOUtils.readAllLinesAndRemoveHeader(stream, 10000);
} catch (IOException e1) {
return "";
}
}
public static List readFileProperties(URI propertiesFile) {
final InputStream stream;
try {
stream = propertiesFile.toURL().openStream();
if (stream == null) {
return null;
}
} catch (Exception e) {
LOG.error("Cannot open library file: {}", propertiesFile, e);
return null;
}
String classpathParent = null;
if ("classpath".equalsIgnoreCase(propertiesFile.getScheme())) {
String path = propertiesFile.getSchemeSpecificPart();
int x = path.lastIndexOf('/');
if (x > -1) {
classpathParent = path.substring(0, x);
}
}
if ("jar".equalsIgnoreCase(propertiesFile.getScheme())) {
String path = propertiesFile.getSchemeSpecificPart();
int x = path.lastIndexOf('/');
if (x > -1) {
path = path.substring(0, x);
x = path.indexOf("!/");
if (x > -1) {
classpathParent = path.substring(x + 1);
}
}
}
String fileParent = null;
if ("file".equalsIgnoreCase(propertiesFile.getScheme())) {
fileParent = (new File(propertiesFile)).getParent();
}
try {
Properties properties = new Properties();
properties.load(stream);
stream.close();
final List result = new ArrayList();
for (String file : properties.stringPropertyNames()) {
try {
URI uri = null;
if (classpathParent != null) {
URL url = ClientHelper.class.getResource(classpathParent + "/" + file);
if (url != null) {
uri = url.toURI();
}
}
if (fileParent != null) {
uri = (new File(fileParent, file)).toURI();
}
if (uri != null) {
result.add(new FileEntry(properties.getProperty(file), uri));
} else {
LOG.error("Cannot find library entry: {}", file);
}
} catch (URISyntaxException e) {
// ignore entry
}
}
Collections.sort(result);
return result;
} catch (IOException e) {
LOG.error("Cannot read library file: {}", propertiesFile);
return null;
} finally {
IOUtils.closeQuietly(stream);
}
}
public static class FileEntry implements Comparable {
private final String name;
private final URI file;
public FileEntry(String name, URI file) {
this.name = name;
this.file = file;
}
public String getName() {
return name;
}
public URI getFile() {
return file;
}
@Override
public String toString() {
return name;
}
@Override
public int compareTo(FileEntry o) {
return name.compareToIgnoreCase(o.getName());
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof FileEntry)) {
return false;
}
return name.equals(((FileEntry) obj).getName());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy