OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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

Rev Author Line No. Line
17 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.openconcerto.openoffice;
15
 
16
import static java.util.Arrays.asList;
17
import org.openconcerto.openoffice.ODPackage.RootElement;
18
 
19
import org.jdom.Document;
20
import org.jdom.Element;
21
import org.jdom.Namespace;
22
 
23
/**
24
 * A {@link ContentType} of a certain version.
25
 *
26
 * @author Sylvain
27
 */
28
public enum ContentTypeVersioned {
29
    TEXT_V1(ContentType.TEXT, XMLVersion.OOo, "application/vnd.sun.xml.writer", "text", "sxw") {
30
    },
31
    GRAPHICS_V1(ContentType.GRAPHICS, XMLVersion.OOo, "application/vnd.sun.xml.draw", "drawing", "sxd") {
32
    },
33
    PRESENTATION_V1(ContentType.PRESENTATION, XMLVersion.OOo, "application/vnd.sun.xml.impress", "presentation", "sxi") {
34
    },
35
    SPREADSHEET_V1(ContentType.SPREADSHEET, XMLVersion.OOo, "application/vnd.sun.xml.calc", "spreadsheet", "sxc") {
36
    },
37
    TEXT(ContentType.TEXT, XMLVersion.OD, "application/vnd.oasis.opendocument.text", "text", "odt") {
38
    },
39
    TEXT_TEMPLATE(ContentType.TEXT, XMLVersion.OD, "application/vnd.oasis.opendocument.text-template", "text", "ott") {
40
    },
41
    GRAPHICS(ContentType.GRAPHICS, XMLVersion.OD, "application/vnd.oasis.opendocument.graphics", "drawing", "odg") {
42
    },
43
    GRAPHICS_TEMPLATE(ContentType.GRAPHICS, XMLVersion.OD, "application/vnd.oasis.opendocument.graphics-template", "drawing", "otg") {
44
    },
45
    PRESENTATION(ContentType.PRESENTATION, XMLVersion.OD, "application/vnd.oasis.opendocument.presentation", "presentation", "odp") {
46
    },
47
    PRESENTATION_TEMPLATE(ContentType.PRESENTATION, XMLVersion.OD, "application/vnd.oasis.opendocument.presentation-template", "presentation", "otp") {
48
    },
49
    SPREADSHEET(ContentType.SPREADSHEET, XMLVersion.OD, "application/vnd.oasis.opendocument.spreadsheet", "spreadsheet", "ods") {
50
    },
51
    SPREADSHEET_TEMPLATE(ContentType.SPREADSHEET, XMLVersion.OD, "application/vnd.oasis.opendocument.spreadsheet-template", "spreadsheet", "ots") {
52
    };
53
 
54
    private final ContentType type;
55
    private final XMLVersion version;
56
    private final String mimeType;
57
    // either office:class of the root element for V1
58
    // or the name of the child of office:body for V2
59
    private final String shortName;
60
    private final String extension;
61
 
62
    private ContentTypeVersioned(ContentType type, XMLVersion version, String mimeType, String bodyChildName, String extension) {
63
        this.type = type;
64
        this.mimeType = mimeType;
65
        this.version = version;
66
        this.shortName = bodyChildName;
67
        this.extension = extension;
68
    }
69
 
70
    public final XMLVersion getVersion() {
71
        return this.version;
72
    }
73
 
74
    public final String getShortName() {
75
        return this.shortName;
76
    }
77
 
78
    /**
79
     * Returns the xpath to the body (from below the root element).
80
     *
81
     * @return the xpath to the body, e.g. "./office:body".
82
     */
83
    public final String getBodyPath() {
84
        return this.getVersion() == XMLVersion.OOo ? "./office:body" : "./office:body/office:" + getShortName();
85
    }
86
 
87
    public final Element getBody(final Document doc) {
88
        final Namespace officeNS = this.getVersion().getOFFICE();
89
        final Element body = doc.getRootElement().getChild("body", officeNS);
90
        if (this.getVersion().equals(XMLVersion.OOo))
91
            return body;
92
        else
93
            return body.getChild(getShortName(), officeNS);
94
    }
95
 
96
    public final String getMimeType() {
97
        return this.mimeType;
98
    }
99
 
100
    public final ContentType getType() {
101
        return this.type;
102
    }
103
 
104
    public final String getExtension() {
105
        return this.extension;
106
    }
107
 
108
    public final boolean isTemplate() {
109
        return this.getMimeType().endsWith(TEMPLATE_SUFFIX);
110
    }
111
 
112
    public final ContentTypeVersioned getTemplate() {
113
        if (this.isTemplate())
114
            return this;
115
        else
116
            return fromMime(getMimeType() + TEMPLATE_SUFFIX);
117
    }
118
 
119
    public final ContentTypeVersioned getNonTemplate() {
120
        if (this.isTemplate())
121
            return fromMime(getMimeType().substring(0, getMimeType().length() - TEMPLATE_SUFFIX.length()));
122
        else
123
            return this;
124
    }
125
 
126
    /**
127
     * Create a new minimal document using {@link RootElement#CONTENT}.
128
     *
19 ilm 129
     * @param version the version.
17 ilm 130
     * @return the body of the created document.
25 ilm 131
     * @see #createContent(XMLFormatVersion, boolean)
17 ilm 132
     */
19 ilm 133
    public final Element createContent(final XMLFormatVersion version) {
134
        return this.createContent(version, false);
17 ilm 135
    }
136
 
137
    /**
138
     * Create a new minimal document.
139
     *
19 ilm 140
     * @param version the version.
17 ilm 141
     * @param singleXML <code>true</code> for {@link RootElement#SINGLE_CONTENT}, <code>false</code>
142
     *        for {@link RootElement#CONTENT}.
143
     * @return the body of the created document.
25 ilm 144
     * @see #createPackage(XMLFormatVersion)
17 ilm 145
     */
19 ilm 146
    public Element createContent(final XMLFormatVersion version, final boolean singleXML) {
147
        checkVersion(version);
17 ilm 148
        final RootElement rootElement = singleXML ? RootElement.SINGLE_CONTENT : RootElement.CONTENT;
25 ilm 149
        final Document doc = rootElement.createDocument(version);
17 ilm 150
        final Namespace officeNS = getVersion().getOFFICE();
151
        setType(doc, rootElement, officeNS);
152
        // don't forget that, otherwise OO crash
153
        doc.getRootElement().addContent(new Element("automatic-styles", officeNS));
154
 
155
        final Element topBody = new Element("body", officeNS);
156
        final Element body;
157
        if (this.getVersion().equals(XMLVersion.OD)) {
158
            body = new Element(this.getShortName(), officeNS);
159
            topBody.addContent(body);
160
        } else
161
            body = topBody;
162
        doc.getRootElement().addContent(topBody);
163
 
164
        return body;
165
    }
166
 
19 ilm 167
    private final void checkVersion(final XMLFormatVersion version) {
168
        if (version.getXMLVersion() != getVersion())
169
            throw new IllegalArgumentException("Version mismatch : " + version.getXMLVersion());
170
    }
171
 
17 ilm 172
    public void setType(final Document doc) {
25 ilm 173
        this.setType(doc, RootElement.fromDocument(doc), getVersion().getOFFICE());
17 ilm 174
    }
175
 
176
    // not safe
177
    private void setType(final Document doc, final RootElement rootElem, final Namespace officeNS) {
178
        final Element root = doc.getRootElement();
179
        assert root.getName().equals(rootElem.getElementName());
180
        if (rootElem != RootElement.CONTENT && rootElem != RootElement.SINGLE_CONTENT)
181
            throw new IllegalArgumentException("the document is not content : " + rootElem);
182
        if (this.getVersion().equals(XMLVersion.OOo)) {
183
            root.setAttribute("class", this.getShortName(), officeNS);
184
        } else if (this.getVersion().equals(XMLVersion.OD)) {
185
            if (rootElem == RootElement.SINGLE_CONTENT) {
186
                root.setAttribute("mimetype", this.getMimeType(), officeNS);
187
            }
188
            // else ODPackage can use the body to infer the type (office:mimetype is only for single
189
            // xml document)
190
        }
191
    }
192
 
193
    /**
194
     * Create a new minimal document using {@link RootElement#STYLES}.
195
     *
19 ilm 196
     * @param version the version.
17 ilm 197
     * @return the created document.
198
     */
19 ilm 199
    public Document createStyles(final XMLFormatVersion version) {
200
        checkVersion(version);
17 ilm 201
        final Namespace officeNS = getVersion().getOFFICE();
25 ilm 202
        final Document styles = RootElement.STYLES.createDocument(version);
17 ilm 203
        // some consumers demand empty children
204
        styles.getRootElement().addContent(asList(new Element("styles", officeNS), new Element("automatic-styles", officeNS), new Element("master-styles", officeNS)));
205
        return styles;
206
    }
207
 
208
    /**
209
     * Creates an empty package.
210
     *
19 ilm 211
     * @param version the version of the package.
17 ilm 212
     * @return a new package with minimal {@link RootElement#CONTENT} and {@link RootElement#STYLES}
213
     */
19 ilm 214
    public ODPackage createPackage(final XMLFormatVersion version) {
25 ilm 215
        return ODPackage.createFromDocuments(this, this.createContent(version, false).getDocument(), this.createStyles(version), null, null);
17 ilm 216
    }
217
 
218
    // *** static
219
 
220
    private static final String TEMPLATE_SUFFIX = "-template";
221
 
222
    static ContentTypeVersioned fromType(ContentType type, XMLVersion version, final boolean template) {
223
        for (final ContentTypeVersioned t : ContentTypeVersioned.values())
224
            if (t.getType().equals(type) && t.getVersion() == version && t.isTemplate() == template)
225
                return t;
226
        return null;
227
    }
228
 
229
    static public ContentTypeVersioned fromMime(String mime) {
230
        for (final ContentTypeVersioned t : ContentTypeVersioned.values())
231
            if (t.getMimeType().equals(mime))
232
                return t;
233
        return null;
234
    }
235
 
25 ilm 236
    static public ContentTypeVersioned fromMime(byte[] mime) {
237
        return fromMime(new String(mime, ODPackage.MIMETYPE_ENC));
238
    }
239
 
240
    static ContentTypeVersioned fromContent(final ODXMLDocument content) {
241
        final ContentTypeVersioned res;
242
        final XMLVersion vers = content.getVersion();
243
        if (vers.equals(XMLVersion.OOo)) {
244
            final Element contentRoot = content.getDocument().getRootElement();
245
            final String docClass = contentRoot.getAttributeValue("class", contentRoot.getNamespace("office"));
246
            res = ContentTypeVersioned.fromClass(docClass);
247
        } else if (vers.equals(XMLVersion.OD)) {
248
            final Element bodyChild = (Element) content.getChild("body").getChildren().get(0);
249
            res = ContentTypeVersioned.fromBody(bodyChild.getName());
250
        } else {
251
            throw new IllegalStateException("Unknown content version : " + vers);
252
        }
253
        assert !res.isTemplate() : "template status cannot be inferred from content";
254
        return res;
255
    }
256
 
17 ilm 257
    static ContentTypeVersioned fromClass(String name) {
258
        return fromShortName(XMLVersion.OOo, name);
259
    }
260
 
261
    static ContentTypeVersioned fromBody(String name) {
262
        return fromShortName(XMLVersion.OD, name);
263
    }
264
 
265
    static private ContentTypeVersioned fromShortName(XMLVersion version, String name) {
266
        if (name == null)
267
            throw new NullPointerException();
268
 
269
        for (final ContentTypeVersioned t : ContentTypeVersioned.values())
270
            if (t.shortName.equals(name) && t.getVersion() == version)
271
                return t;
272
        return null;
273
    }
274
}