All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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