OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 142 | Rev 149 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
13 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.jopendocument.link;
15
 
16
import org.openconcerto.utils.CollectionUtils;
17
 
18
import java.io.File;
19
import java.io.FileNotFoundException;
73 ilm 20
import java.io.FilePermission;
13 ilm 21
import java.io.IOException;
22
import java.net.MalformedURLException;
73 ilm 23
import java.net.SocketPermission;
13 ilm 24
import java.net.URL;
25
import java.net.URLClassLoader;
73 ilm 26
import java.security.CodeSource;
27
import java.security.PermissionCollection;
13 ilm 28
import java.util.List;
29
import java.util.Map;
73 ilm 30
import java.util.PropertyPermission;
13 ilm 31
import java.util.WeakHashMap;
32
 
33
/**
34
 * Connexion avec une instance d'OO
35
 *
36
 * @author Administrateur
37
 */
144 ilm 38
public abstract class OOConnexion implements AutoCloseable {
13 ilm 39
 
40
    // weak to let go OOInstallation instances
41
    private static final Map<OOInstallation, ClassLoader> loaders = new WeakHashMap<OOInstallation, ClassLoader>(2);
42
    // TODO use OOInstallation.getVersion()
43
    // for now only one version (but also works with OO2)
44
    private static final String OO_VERSION = "3";
73 ilm 45
 
46
    protected static final int PORT = 8100;
144 ilm 47
    protected static final int PORT_MAX = 8250;
73 ilm 48
 
13 ilm 49
    static {
50
        // needed to access .class inside a jar inside a jar.
51
        org.openconcerto.utils.protocol.Helper.register();
52
    }
53
 
54
    static private final URL[] getURLs(final OOInstallation ooInstall) {
55
        final List<URL> res = ooInstall.getURLs(CollectionUtils.createSet("ridl.jar", "jurt.jar", "juh.jar", "unoil.jar"));
56
 
57
        final String jarName = "OO" + OO_VERSION + "-link.jar";
58
        final URL resource = OOConnexion.class.getResource(jarName);
59
        if (resource == null)
60
            // Did you run ant in the OO3Link project (or in ours) ?
61
            throw new IllegalStateException("Missing " + jarName);
62
        res.add(org.openconcerto.utils.protocol.Helper.toJarJar(resource));
63
 
64
        return res.toArray(new URL[res.size()]);
65
    }
66
 
67
    static private final ClassLoader getLoader(final OOInstallation ooInstall) {
68
        ClassLoader res = loaders.get(ooInstall);
69
        if (res == null) {
70
            // pass our classloader otherwise the system class loader will be used. This won't work
71
            // in webstart since the classpath is loaded by JNLPClassLoader, thus a class loaded by
72
            // res couldn't refer to the classpath (e.g. this class) but only to the java library.
73 ilm 73
            res = new URLClassLoader(getURLs(ooInstall), OOConnexion.class.getClassLoader()) {
74
                @Override
75
                protected PermissionCollection getPermissions(CodeSource codesource) {
76
                    final PermissionCollection perms = super.getPermissions(codesource);
77
                    perms.add(new FilePermission(ooInstall.getExecutable().getAbsolutePath(), "execute"));
144 ilm 78
                    perms.add(new SocketPermission("localhost:" + PORT + "-" + PORT_MAX, "connect"));
73 ilm 79
                    // needed by OO jars
80
                    perms.add(new PropertyPermission("*", "read"));
81
                    // to be able to open any document
82
                    perms.add(new FilePermission("<<ALL FILES>>", "read"));
83
                    // needed by ThreadPoolExecutor.shutdown()
84
                    perms.add(new RuntimePermission("modifyThread"));
85
                    return perms;
86
                }
87
            };
13 ilm 88
            loaders.put(ooInstall, res);
89
        }
90
        return res;
91
    }
92
 
93
    /**
94
     * Return a connection to the default OpenOffice installation.
95
     *
96
     * @return a connection to the default OpenOffice or <code>null</code> if none is found.
97
     * @throws IllegalStateException if an error occurs while searching.
98
     */
99
    static public OOConnexion create() throws IllegalStateException {
100
        final OOInstallation ooInstall;
101
        try {
102
            ooInstall = OOInstallation.getInstance();
103
        } catch (IOException e) {
104
            throw new IllegalStateException("Couldn't find default OO installation", e);
105
        }
106
        return create(ooInstall);
107
    }
108
 
109
    static public OOConnexion create(final OOInstallation ooInstall) throws IllegalStateException {
110
        if (ooInstall == null)
111
            return null;
112
        try {
113
            final Class<?> c = getLoader(ooInstall).loadClass("org.jopendocument.link" + OO_VERSION + ".OOConnexion");
114
            return (OOConnexion) c.getConstructor(OOInstallation.class).newInstance(ooInstall);
115
        } catch (Exception e) {
116
            throw new IllegalStateException("Couldn't create OOCOnnexion", e);
117
        }
118
    }
119
 
73 ilm 120
    public static void main(String[] args) throws IOException {
142 ilm 121
        if (args.length == 0 || args.length > 2) {
122
            System.out.println("Usage : " + OOConnexion.class.getName() + " officeFile | --type param");
73 ilm 123
            System.out.println("Open officeFile in the default installation of LibreOffice");
142 ilm 124
            System.out.println("--type is either file or url");
73 ilm 125
            System.exit(1);
126
        }
144 ilm 127
        try (final OOConnexion conn = OOConnexion.create()) {
128
            if (conn == null)
129
                throw new IllegalStateException("No Office found");
130
            final boolean file;
131
            final String arg;
132
            if (args.length == 1) {
133
                file = true;
134
                arg = args[0];
135
            } else if (args[0].equals("--file")) {
136
                file = true;
137
                arg = args[1];
138
            } else if (args[0].equals("--url")) {
139
                file = false;
140
                arg = args[1];
141
            } else {
142
                throw new IllegalArgumentException("Type not valid : " + args[0]);
143
            }
144
            if (file)
145
                conn.loadDocument(new File(arg), false);
146
            else
147
                conn.loadDocumentFromURLAsync(arg, false);
142 ilm 148
        }
73 ilm 149
    }
150
 
13 ilm 151
    protected abstract Component loadDocumentFromURLAsync(final String url, final boolean hidden);
152
 
153
    /**
154
     * Load a document in OpenOffice.
155
     *
156
     * @param f the file to load.
157
     * @param hidden <code>true</code> if no frame should be visible.
158
     * @return the new component.
159
     * @throws IOException if an error occurs.
160
     */
161
    public final Component loadDocument(final File f, final boolean hidden) throws IOException {
162
        if (!f.exists())
163
            throw new FileNotFoundException(f.getAbsolutePath());
164
 
165
        return loadDocumentFromURLAsync(convertToUrl(f.getAbsolutePath()), hidden);
166
    }
167
 
168
    protected abstract String convertToUrl(String path) throws MalformedURLException;
169
 
144 ilm 170
    @Override
171
    public final void close() {
172
        this.closeConnexion();
173
    }
174
 
13 ilm 175
    public abstract void closeConnexion();
176
 
177
    /**
178
     * Whether the bridge is closed.
179
     *
180
     * @return <code>true</code> if {@link #closeConnexion()} was called or OpenOffice is now longer
181
     *         running.
182
     */
183
    public abstract boolean isClosed();
184
}