You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HPBFPart.java 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hpbf.model;
  16. import java.io.FileNotFoundException;
  17. import java.io.IOException;
  18. import java.io.InputStream;
  19. import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream;
  20. import org.apache.poi.poifs.filesystem.DirectoryNode;
  21. import org.apache.poi.poifs.filesystem.Entry;
  22. import org.apache.poi.util.IOUtils;
  23. /**
  24. * Parent class of all HPBF sub-parts, handling
  25. * the fiddly reading in / writing out bits
  26. * for all of them.
  27. */
  28. public abstract class HPBFPart {
  29. private byte[] data;
  30. private final String[] path;
  31. /**
  32. * @param path the path to the part, eg Contents or Quill, QuillSub, CONTENTS
  33. */
  34. public HPBFPart(DirectoryNode baseDir, String[] path) throws IOException {
  35. this.path = path;
  36. DirectoryNode dir = getDir(baseDir, path);
  37. String name = path[path.length-1];
  38. if (!dir.hasEntry(name)) {
  39. throw new IllegalArgumentException("File invalid - failed to find document entry '" + name + "'");
  40. }
  41. // Grab the data from the part stream
  42. try (InputStream is = dir.createDocumentInputStream(name)) {
  43. data = IOUtils.toByteArray(is);
  44. }
  45. }
  46. private static DirectoryNode getDir(DirectoryNode baseDir, String[] path) {
  47. DirectoryNode dir = baseDir;
  48. for(int i=0; i<path.length-1; i++) {
  49. try {
  50. Entry entry = dir.getEntry(path[i]);
  51. if (!(entry instanceof DirectoryNode)) {
  52. throw new IllegalArgumentException("Had unexpected type of entry for path: " + path[i] + ": " + entry);
  53. }
  54. dir = (DirectoryNode) entry;
  55. } catch (FileNotFoundException e) {
  56. throw new IllegalArgumentException("File invalid - failed to find directory entry '"
  57. + path[i] + "': " + e);
  58. }
  59. }
  60. return dir;
  61. }
  62. public void writeOut(DirectoryNode baseDir) throws IOException {
  63. String[] path = getPath();
  64. // Ensure that all parent directories exist
  65. DirectoryNode dir = baseDir;
  66. for(int i=0; i<path.length-1; i++) {
  67. try {
  68. dir = (DirectoryNode)dir.getEntry(path[i]);
  69. } catch(FileNotFoundException e) {
  70. dir.createDirectory(path[i]);
  71. }
  72. }
  73. // Update the byte array with the latest data
  74. generateData();
  75. // Write out
  76. try (UnsynchronizedByteArrayInputStream bais = UnsynchronizedByteArrayInputStream.builder().setByteArray(data).get()) {
  77. dir.createDocument(path[path.length-1], bais);
  78. }
  79. }
  80. /**
  81. * Called just before writing out, to trigger
  82. * the data byte array to be updated with the
  83. * latest contents.
  84. */
  85. protected abstract void generateData();
  86. /**
  87. * Returns the raw data that makes up
  88. * this document part.
  89. */
  90. public final byte[] getData() {
  91. return data;
  92. }
  93. protected final void setData(byte[] data) {
  94. this.data = data.clone();
  95. }
  96. /**
  97. * Returns
  98. */
  99. public final String[] getPath() {
  100. return path;
  101. }
  102. }