LibreOffice Module xmerge (master)  1
OfficeZip.java
Go to the documentation of this file.
1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  * Licensed to the Apache Software Foundation (ASF) under one or more
11  * contributor license agreements. See the NOTICE file distributed
12  * with this work for additional information regarding copyright
13  * ownership. The ASF licenses this file to you under the Apache
14  * License, Version 2.0 (the "License"); you may not use this file
15  * except in compliance with the License. You may obtain a copy of
16  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package org.openoffice.xmerge.converter.xml;
20 
21 import java.util.List;
22 import java.util.ListIterator;
23 import java.util.LinkedList;
24 import java.util.zip.ZipInputStream;
25 import java.util.zip.ZipOutputStream;
26 import java.util.zip.ZipEntry;
27 import java.util.zip.CRC32;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.io.IOException;
31 import java.io.ByteArrayOutputStream;
32 
34 
40 class OfficeZip {
41 
43  private static final String CONTENTXML = "content.xml";
44 
45  private static final String STYLEXML = "styles.xml";
46  private static final String METAXML = "meta.xml";
47  private static final String SETTINGSXML = "settings.xml";
48  private static final String MANIFESTXML = "META-INF/manifest.xml";
49 
50  private static final int BUFFERSIZE = 1024;
51 
52  private final List<Entry> entryList;
53 
54  private int contentIndex = -1;
55  private int styleIndex = -1;
56  private int metaIndex = -1;
57  private int settingsIndex = -1;
58  private int manifestIndex = -1;
59 
61  OfficeZip() {
62 
63  entryList = new LinkedList<Entry>();
64  }
65 
81  void read(InputStream is) throws IOException {
82 
83  ZipInputStream zis = new ZipInputStream(is);
84  ZipEntry ze;
85  int i = -1;
86 
87  while ((ze = zis.getNextEntry()) != null) {
88 
89  String name = ze.getName();
90 
91  Debug.log(Debug.TRACE, "reading entry: " + name);
92 
93  ByteArrayOutputStream baos = new ByteArrayOutputStream();
94 
95  int len;
96  byte buffer[] = new byte[BUFFERSIZE];
97 
98  while ((len = zis.read(buffer)) > 0) {
99  baos.write(buffer, 0, len);
100  }
101 
102  byte bytes[] = baos.toByteArray();
103  Entry entry = new Entry(ze,bytes);
104 
105  entryList.add(entry);
106 
107  i++;
108 
109  if (name.equalsIgnoreCase(CONTENTXML)) {
110  contentIndex = i;
111  }
112  else if (name.equalsIgnoreCase(STYLEXML)) {
113  styleIndex = i;
114  }
115  else if (name.equalsIgnoreCase(METAXML)) {
116  metaIndex = i;
117  }
118  else if (name.equalsIgnoreCase(SETTINGSXML)) {
119  settingsIndex = i;
120  }
121  else if (name.equalsIgnoreCase(MANIFESTXML)) {
122  manifestIndex = i;
123  }
124 
125  }
126 
127  zis.close();
128  }
129 
137  byte[] getContentXMLBytes() {
138 
139  return getEntryBytes(contentIndex);
140  }
141 
150  byte[] getStyleXMLBytes() {
151 
152  return getEntryBytes(styleIndex);
153  }
154 
163  byte[] getMetaXMLBytes() {
164  return getEntryBytes(metaIndex);
165  }
166 
175  byte[] getSettingsXMLBytes() {
176  return getEntryBytes(settingsIndex);
177  }
178 
187  byte[] getManifestXMLBytes() {
188  return getEntryBytes(manifestIndex);
189  }
190 
200  byte[] getNamedBytes(String name) {
201 
202  // The list is not sorted, and sorting it for a binary search would
203  // invalidate the indices stored for the main files.
204 
205  // Could improve performance by caching the name and index when
206  // iterating through the ZipFile in read().
207  for (int i = 0; i < entryList.size(); i++) {
208  Entry e = entryList.get(i);
209 
210  if (e.zipEntry.getName().equals(name)) {
211  return getEntryBytes(i);
212  }
213  }
214 
215  return null;
216  }
217 
229  void setNamedBytes(String name, byte[] bytes) {
230  for (int i = 0; i < entryList.size(); i++) {
231  Entry e = entryList.get(i);
232 
233  if (e.zipEntry.getName().equals(name)) {
234  setEntryBytes(i, bytes, name);
235  return;
236  }
237  }
238 
239  // If we're here, no entry was found. Call setEntryBytes with an index
240  // of -1 to insert a new entry.
241  setEntryBytes(-1, bytes, name);
242  }
243 
254  private byte[] getEntryBytes(int index) {
255 
256  byte[] bytes = null;
257 
258  if (index > -1) {
259  Entry entry = entryList.get(index);
260  bytes = entry.bytes;
261  }
262  return bytes;
263  }
264 
270  void setContentXMLBytes(byte bytes[]) {
271 
272  contentIndex = setEntryBytes(contentIndex, bytes, CONTENTXML);
273  }
274 
280  void setStyleXMLBytes(byte bytes[]) {
281 
282  styleIndex = setEntryBytes(styleIndex, bytes, STYLEXML);
283  }
284 
290  void setMetaXMLBytes(byte bytes[]) {
291 
292  metaIndex = setEntryBytes(metaIndex, bytes, METAXML);
293  }
294 
300  void setSettingsXMLBytes(byte bytes[]) {
301 
302  settingsIndex = setEntryBytes(settingsIndex, bytes, SETTINGSXML);
303  }
304 
310  void setManifestXMLBytes(byte bytes[]) {
311  manifestIndex = setEntryBytes(manifestIndex, bytes, MANIFESTXML);
312  }
313 
328  private int setEntryBytes(int index, byte bytes[], String name) {
329 
330  if (index > -1) {
331  // replace existing entry in entryList
332  Entry entry = entryList.get(index);
333  name = entry.zipEntry.getName();
334  int method = entry.zipEntry.getMethod();
335 
336  ZipEntry ze = createZipEntry(name, bytes, method);
337 
338  entry.zipEntry = ze;
339  entry.bytes= bytes;
340 
341  } else {
342  // add a new entry into entryList
343  ZipEntry ze = createZipEntry(name, bytes, ZipEntry.DEFLATED);
344  Entry entry = new Entry(ze, bytes);
345  entryList.add(entry);
346  index = entryList.size() - 1;
347  }
348 
349  return index;
350  }
351 
359  void write(OutputStream os) throws IOException {
360 
361  Debug.log(Debug.TRACE, "Writing out the following entries into zip.");
362 
363  ZipOutputStream zos = new ZipOutputStream(os);
364 
365  ListIterator<Entry> iterator = entryList.listIterator();
366  while (iterator.hasNext()) {
367 
368  Entry entry = iterator.next();
369  ZipEntry ze = entry.zipEntry;
370 
371  String name = ze.getName();
372 
373  Debug.log(Debug.TRACE, "... " + name);
374 
375  zos.putNextEntry(ze);
376  zos.write(entry.bytes);
377  }
378 
379  zos.close();
380  }
381 
391  private ZipEntry createZipEntry(String name, byte bytes[], int method) {
392 
393  ZipEntry ze = new ZipEntry(name);
394 
395  ze.setMethod(method);
396  ze.setSize(bytes.length);
397 
398  CRC32 crc = new CRC32();
399  crc.reset();
400  crc.update(bytes);
401  ze.setCrc(crc.getValue());
402 
403  ze.setTime(System.currentTimeMillis());
404 
405  return ze;
406  }
407 
414  private static class Entry {
415 
416  ZipEntry zipEntry = null;
417  byte bytes[] = null;
418 
419  Entry(ZipEntry zipEntry, byte bytes[]) {
420  this.zipEntry = zipEntry;
421  this.bytes = bytes;
422  }
423  }
424 }
void reset()
Provides general purpose utilities.
std::vector< sal_uInt8 > bytes
void update(const css::uno::Sequence< sal_Int8 > &b)
std::deque< std::string > LinkedList
exports com.sun.star. java
sal_Int32 getValue() const
int i
This inner class is used as a data structure for holding a.
Definition: OfficeZip.java:414
unsigned char byte
const char * name
Provides interfaces for converting between two.
Definition: Convert.java:19
This class is used for logging debug messages.
Definition: Debug.java:39