Browse Source

Changed CRLF to LF in ooxml/java. Minor fixes for compiler warnings and formatting

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@776607 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_5_BETA6
Josh Micich 15 years ago
parent
commit
95a7539c30
56 changed files with 7716 additions and 7713 deletions
  1. 69
    69
      src/ooxml/java/org/apache/poi/POIXMLException.java
  2. 47
    48
      src/ooxml/java/org/apache/poi/POIXMLFactory.java
  3. 122
    122
      src/ooxml/java/org/apache/poi/POIXMLRelation.java
  4. 26
    27
      src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java
  5. 32
    32
      src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java
  6. 34
    34
      src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java
  7. 34
    34
      src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java
  8. 32
    33
      src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java
  9. 47
    47
      src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java
  10. 43
    43
      src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java
  11. 130
    131
      src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java
  12. 29
    29
      src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java
  13. 33
    33
      src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java
  14. 52
    52
      src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java
  15. 81
    81
      src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java
  16. 506
    509
      src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
  17. 77
    77
      src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
  18. 622
    622
      src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java
  19. 77
    77
      src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java
  20. 32
    32
      src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java
  21. 460
    465
      src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
  22. 224
    224
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java
  23. 91
    91
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java
  24. 96
    96
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java
  25. 49
    49
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java
  26. 50
    50
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java
  27. 163
    163
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
  28. 45
    45
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java
  29. 433
    434
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java
  30. 63
    64
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java
  31. 191
    193
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java
  32. 78
    78
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalCertificatePart.java
  33. 28
    28
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalSignatureOriginPart.java
  34. 393
    391
      src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java
  35. 70
    70
      src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignature.java
  36. 22
    22
      src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignatureManager.java
  37. 72
    71
      src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java
  38. 91
    90
      src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java
  39. 43
    42
      src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java
  40. 37
    36
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java
  41. 82
    81
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java
  42. 220
    219
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java
  43. 122
    121
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java
  44. 248
    247
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
  45. 180
    180
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java
  46. 75
    74
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java
  47. 350
    349
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java
  48. 151
    150
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java
  49. 186
    185
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java
  50. 180
    179
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java
  51. 32
    32
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java
  52. 190
    189
      src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
  53. 626
    626
      src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java
  54. 66
    65
      src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
  55. 74
    73
      src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java
  56. 110
    109
      src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java

+ 69
- 69
src/ooxml/java/org/apache/poi/POIXMLException.java View File

@@ -1,69 +1,69 @@
/* ====================================================================
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.poi;
/**
* Indicates a generic OOXML error.
*
* @author Yegor Kozlov
*/
public class POIXMLException extends RuntimeException{
/**
* Create a new <code>POIXMLException</code> with no
* detail mesage.
*/
public POIXMLException() {
super();
}
/**
* Create a new <code>POIXMLException</code> with
* the <code>String</code> specified as an error message.
*
* @param msg The error message for the exception.
*/
public POIXMLException(String msg) {
super(msg);
}
/**
* Create a new <code>POIXMLException</code> with
* the <code>String</code> specified as an error message and the cause.
*
* @param msg The error message for the exception.
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public POIXMLException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Create a new <code>POIXMLException</code> with
* the specified cause.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public POIXMLException(Throwable cause) {
super(cause);
}
}
/* ====================================================================
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.poi;
/**
* Indicates a generic OOXML error.
*
* @author Yegor Kozlov
*/
public final class POIXMLException extends RuntimeException{
/**
* Create a new <code>POIXMLException</code> with no
* detail mesage.
*/
public POIXMLException() {
super();
}
/**
* Create a new <code>POIXMLException</code> with
* the <code>String</code> specified as an error message.
*
* @param msg The error message for the exception.
*/
public POIXMLException(String msg) {
super(msg);
}
/**
* Create a new <code>POIXMLException</code> with
* the <code>String</code> specified as an error message and the cause.
*
* @param msg The error message for the exception.
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public POIXMLException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Create a new <code>POIXMLException</code> with
* the specified cause.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public POIXMLException(Throwable cause) {
super(cause);
}
}

+ 47
- 48
src/ooxml/java/org/apache/poi/POIXMLFactory.java View File

@@ -1,48 +1,47 @@
/* ====================================================================
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.poi;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;
/**
* Defines a factory API that enables sub-classes to create instances of <code>POIXMLDocumentPart</code>
*
* @author Yegor Kozlov
*/
public abstract class POIXMLFactory {
/**
* Create a POIXMLDocumentPart from existing package part and relation. This method is called
* from {@link POIXMLDocumentPart#read(POIXMLFactory)} when parsing a document
*
* @param rel the package part relationship
* @param part the PackagePart representing the created instance
* @return A new instance of a POIXMLDocumentPart.
*/
public abstract POIXMLDocumentPart createDocumentPart(PackageRelationship rel, PackagePart part);
/**
* Create a new POIXMLDocumentPart using the supplied descriptor. This method is used when adding new parts
* to a document, for example, when adding a sheet to a workbook, slide to a presentation, etc.
*
* @param descriptor describes the object to create
* @return A new instance of a POIXMLDocumentPart.
*/
public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor);
}
/* ====================================================================
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.poi;

import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;

/**
* Defines a factory API that enables sub-classes to create instances of <code>POIXMLDocumentPart</code>
*
* @author Yegor Kozlov
*/
public abstract class POIXMLFactory {

/**
* Create a POIXMLDocumentPart from existing package part and relation. This method is called
* from {@link POIXMLDocumentPart#read(POIXMLFactory)} when parsing a document
*
* @param rel the package part relationship
* @param part the PackagePart representing the created instance
* @return A new instance of a POIXMLDocumentPart.
*/
public abstract POIXMLDocumentPart createDocumentPart(PackageRelationship rel, PackagePart part);

/**
* Create a new POIXMLDocumentPart using the supplied descriptor. This method is used when adding new parts
* to a document, for example, when adding a sheet to a workbook, slide to a presentation, etc.
*
* @param descriptor describes the object to create
* @return A new instance of a POIXMLDocumentPart.
*/
public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor);
}

+ 122
- 122
src/ooxml/java/org/apache/poi/POIXMLRelation.java View File

@@ -1,122 +1,122 @@
/* ====================================================================
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.poi;
/**
* Represents a descriptor of a OOXML relation.
*
* @author Yegor Kozlov
*/
public abstract class POIXMLRelation {
/**
* Describes the content stored in a part.
*/
protected String _type;
/**
* The kind of connection between a source part and a target part in a package.
*/
protected String _relation;
/**
* The path component of a pack URI.
*/
protected String _defaultName;
/**
* Defines what object is used to construct instances of this relationship
*/
private Class<? extends POIXMLDocumentPart> _cls;
/**
* Instantiates a POIXMLRelation.
*
* @param type content type
* @param rel relationship
* @param defaultName default item name
* @param cls defines what object is used to construct instances of this relationship
*/
public POIXMLRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
_type = type;
_relation = rel;
_defaultName = defaultName;
_cls = cls;
}
/**
* Instantiates a POIXMLRelation.
*
* @param type content type
* @param rel relationship
* @param defaultName default item name
*/
public POIXMLRelation(String type, String rel, String defaultName) {
this(type, rel, defaultName, null);
}
/**
* Return the content type. Content types define a media type, a subtype, and an
* optional set of parameters, as defined in RFC 2616.
*
* @return the content type
*/
public String getContentType() {
return _type;
}
/**
* Return the relationship, the kind of connection between a source part and a target part in a package.
* Relationships make the connections between parts directly discoverable without looking at the content
* in the parts, and without altering the parts themselves.
*
* @return the relationship
*/
public String getRelation() {
return _relation;
}
/**
* Return the default part name. Part names are used to refer to a part in the context of a
* package, typically as part of a URI.
*
* @return the default part name
*/
public String getDefaultFileName() {
return _defaultName;
}
/**
* Returns the filename for the nth one of these,
* eg /xl/comments4.xml
*/
public String getFileName(int index) {
if(_defaultName.indexOf("#") == -1) {
// Generic filename in all cases
return getDefaultFileName();
}
return _defaultName.replace("#", Integer.toString(index));
}
/**
* Return type of the obejct used to construct instances of this relationship
*
* @return the class of the object used to construct instances of this relation
*/
public Class<? extends POIXMLDocumentPart> getRelationClass(){
return _cls;
}
}
/* ====================================================================
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.poi;
/**
* Represents a descriptor of a OOXML relation.
*
* @author Yegor Kozlov
*/
public abstract class POIXMLRelation {
/**
* Describes the content stored in a part.
*/
protected String _type;
/**
* The kind of connection between a source part and a target part in a package.
*/
protected String _relation;
/**
* The path component of a pack URI.
*/
protected String _defaultName;
/**
* Defines what object is used to construct instances of this relationship
*/
private Class<? extends POIXMLDocumentPart> _cls;
/**
* Instantiates a POIXMLRelation.
*
* @param type content type
* @param rel relationship
* @param defaultName default item name
* @param cls defines what object is used to construct instances of this relationship
*/
public POIXMLRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
_type = type;
_relation = rel;
_defaultName = defaultName;
_cls = cls;
}
/**
* Instantiates a POIXMLRelation.
*
* @param type content type
* @param rel relationship
* @param defaultName default item name
*/
public POIXMLRelation(String type, String rel, String defaultName) {
this(type, rel, defaultName, null);
}
/**
* Return the content type. Content types define a media type, a subtype, and an
* optional set of parameters, as defined in RFC 2616.
*
* @return the content type
*/
public String getContentType() {
return _type;
}
/**
* Return the relationship, the kind of connection between a source part and a target part in a package.
* Relationships make the connections between parts directly discoverable without looking at the content
* in the parts, and without altering the parts themselves.
*
* @return the relationship
*/
public String getRelation() {
return _relation;
}
/**
* Return the default part name. Part names are used to refer to a part in the context of a
* package, typically as part of a URI.
*
* @return the default part name
*/
public String getDefaultFileName() {
return _defaultName;
}
/**
* Returns the filename for the nth one of these,
* e.g. /xl/comments4.xml
*/
public String getFileName(int index) {
if(_defaultName.indexOf("#") == -1) {
// Generic filename in all cases
return getDefaultFileName();
}
return _defaultName.replace("#", Integer.toString(index));
}
/**
* Return type of the obejct used to construct instances of this relationship
*
* @return the class of the object used to construct instances of this relation
*/
public Class<? extends POIXMLDocumentPart> getRelationClass(){
return _cls;
}
}

+ 26
- 27
src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java View File

@@ -1,27 +1,26 @@
/* ====================================================================
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.poi.openxml4j.exceptions;
@SuppressWarnings("serial")
public class InvalidFormatException extends OpenXML4JException{
public InvalidFormatException(String message){
super(message);
}
}
/* ====================================================================
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.poi.openxml4j.exceptions;

@SuppressWarnings("serial")
public final class InvalidFormatException extends OpenXML4JException{

public InvalidFormatException(String message){
super(message);
}
}

+ 32
- 32
src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java View File

@@ -1,32 +1,32 @@
/* ====================================================================
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.poi.openxml4j.exceptions;
/**
* Throw when an invalid operation is done.
*
* @author Julien Chable
* @version 1.0
*/
@SuppressWarnings("serial")
public class InvalidOperationException extends OpenXML4JRuntimeException{
public InvalidOperationException(String message){
super(message);
}
}
/* ====================================================================
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.poi.openxml4j.exceptions;
/**
* Throw when an invalid operation is done.
*
* @author Julien Chable
* @version 1.0
*/
@SuppressWarnings("serial")
public final class InvalidOperationException extends OpenXML4JRuntimeException{
public InvalidOperationException(String message){
super(message);
}
}

+ 34
- 34
src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java View File

@@ -1,34 +1,34 @@
/* ====================================================================
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.poi.openxml4j.exceptions;
/**
* Global exception throws when a critical error occurs. (this exception is not
* set as Runtime in order to force user to manage the exception in a
* try/catch).
*
* @author CDubettier, Julien Chable
* @version 1.0
*/
@SuppressWarnings("serial")
public class OpenXML4JException extends Exception {
public OpenXML4JException(String msg) {
super(msg);
}
}
/* ====================================================================
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.poi.openxml4j.exceptions;
/**
* Global exception throws when a critical error occurs. (this exception is not
* set as Runtime in order to force user to manage the exception in a
* try/catch).
*
* @author CDubettier, Julien Chable
* @version 1.0
*/
@SuppressWarnings("serial")
public class OpenXML4JException extends Exception {
public OpenXML4JException(String msg) {
super(msg);
}
}

+ 34
- 34
src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java View File

@@ -1,34 +1,34 @@
/* ====================================================================
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.poi.openxml4j.exceptions;
/**
* Global exception throws when a critical error occurs (this exception is
* set as Runtime in order not to force the user to manage the exception in a
* try/catch).
*
* @author Julien Chable
* @version 1.0
*/
@SuppressWarnings("serial")
public class OpenXML4JRuntimeException extends RuntimeException {
public OpenXML4JRuntimeException(String msg) {
super(msg);
}
}
/* ====================================================================
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.poi.openxml4j.exceptions;
/**
* Global exception throws when a critical error occurs (this exception is
* set as Runtime in order not to force the user to manage the exception in a
* try/catch).
*
* @author Julien Chable
* @version 1.0
*/
@SuppressWarnings("serial")
public class OpenXML4JRuntimeException extends RuntimeException {
public OpenXML4JRuntimeException(String msg) {
super(msg);
}
}

+ 32
- 33
src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java View File

@@ -1,33 +1,32 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies the location where the X.509 certificate that is used in signing is stored.
*
* @author Julien Chable
* @version 1.0
*/
public enum CertificateEmbeddingOption {
/** The certificate is embedded in its own PackagePart. */
IN_CERTIFICATE_PART,
/** The certificate is embedded in the SignaturePart that is created for the signature being added. */
IN_SIGNATURE_PART,
/** The certificate in not embedded in the package. */
NOT_EMBEDDED
}
/* ====================================================================
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.poi.openxml4j.opc;

/**
* Specifies the location where the X.509 certificate that is used in signing is stored.
*
* @author Julien Chable
*/
public enum CertificateEmbeddingOption {
/** The certificate is embedded in its own PackagePart. */
IN_CERTIFICATE_PART,
/** The certificate is embedded in the SignaturePart that is created for the signature being added. */
IN_SIGNATURE_PART,
/** The certificate in not embedded in the package. */
NOT_EMBEDDED
}

+ 47
- 47
src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java View File

@@ -1,47 +1,47 @@
/* ====================================================================
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.poi.openxml4j.opc;
import java.util.zip.Deflater;
/**
* Specifies the compression level for content that is stored in a PackagePart.
*
* @author Julien Chable
* @version 1.0
*/
public enum CompressionOption {
/** Compression is optimized for performance. */
FAST(Deflater.BEST_SPEED),
/** Compression is optimized for size. */
MAXIMUM(Deflater.BEST_COMPRESSION),
/** Compression is optimized for a balance between size and performance. */
NORMAL(Deflater.DEFAULT_COMPRESSION),
/** Compression is turned off. */
NOT_COMPRESSED(Deflater.NO_COMPRESSION);
private final int value;
CompressionOption(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
/* ====================================================================
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.poi.openxml4j.opc;
import java.util.zip.Deflater;
/**
* Specifies the compression level for content that is stored in a PackagePart.
*
* @author Julien Chable
* @version 1.0
*/
public enum CompressionOption {
/** Compression is optimized for performance. */
FAST(Deflater.BEST_SPEED),
/** Compression is optimized for size. */
MAXIMUM(Deflater.BEST_COMPRESSION),
/** Compression is optimized for a balance between size and performance. */
NORMAL(Deflater.DEFAULT_COMPRESSION),
/** Compression is turned off. */
NOT_COMPRESSED(Deflater.NO_COMPRESSION);
private final int value;
CompressionOption(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}

+ 43
- 43
src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java View File

@@ -1,43 +1,43 @@
/* ====================================================================
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.poi.openxml4j.opc;
import java.io.File;
/**
* Storage class for configuration storage parameters.
* TODO xml syntax checking is no longer done with DOM4j parser -> remove the schema or do it ?
*
* @author CDubettier, Julen Chable
* @version 1.0
*/
public class Configuration {
// TODO configuration by default. should be clearly stated that it should be
// changed to match installation path
// as schemas dir is needed in runtime
static private String pathForXmlSchema = System.getProperty("user.dir")
+ File.separator + "src" + File.separator + "schemas";
public static String getPathForXmlSchema() {
return pathForXmlSchema;
}
public static void setPathForXmlSchema(String pathForXmlSchema) {
Configuration.pathForXmlSchema = pathForXmlSchema;
}
}
/* ====================================================================
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.poi.openxml4j.opc;
import java.io.File;
/**
* Storage class for configuration storage parameters.
* TODO xml syntax checking is no longer done with DOM4j parser -> remove the schema or do it ?
*
* @author CDubettier, Julen Chable
* @version 1.0
*/
public final class Configuration {
// TODO configuration by default. should be clearly stated that it should be
// changed to match installation path
// as schemas dir is needed in runtime
static private String pathForXmlSchema = System.getProperty("user.dir")
+ File.separator + "src" + File.separator + "schemas";
public static String getPathForXmlSchema() {
return pathForXmlSchema;
}
public static void setPathForXmlSchema(String pathForXmlSchema) {
Configuration.pathForXmlSchema = pathForXmlSchema;
}
}

+ 130
- 131
src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java View File

@@ -1,131 +1,130 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Open Packaging Convention content types (see Annex F : Standard Namespaces
* and Content Types).
*
* @author CDubettier define some constants, Julien Chable
* @version 0.1
*/
public class ContentTypes {
/*
* Open Packaging Convention (Annex F : Standard Namespaces and Content
* Types)
*/
/**
* Core Properties part.
*/
public static final String CORE_PROPERTIES_PART = "application/vnd.openxmlformats-package.core-properties+xml";
/**
* Digital Signature Certificate part.
*/
public static final String DIGITAL_SIGNATURE_CERTIFICATE_PART = "application/vnd.openxmlformats-package.digital-signature-certificate";
/**
* Digital Signature Origin part.
*/
public static final String DIGITAL_SIGNATURE_ORIGIN_PART = "application/vnd.openxmlformats-package.digital-signature-origin";
/**
* Digital Signature XML Signature part.
*/
public static final String DIGITAL_SIGNATURE_XML_SIGNATURE_PART = "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml";
/**
* Relationships part.
*/
public static final String RELATIONSHIPS_PART = "application/vnd.openxmlformats-package.relationships+xml";
/**
* Custom XML part.
*/
public static final String CUSTOM_XML_PART = "application/vnd.openxmlformats-officedocument.customXmlProperties+xml";
/**
* Plain old xml. Note - OOXML uses application/xml, and not text/xml!
*/
public static final String PLAIN_OLD_XML = "application/xml";
public static final String IMAGE_JPEG = "image/jpeg";
public static final String EXTENSION_JPG_1 = "jpg";
public static final String EXTENSION_JPG_2 = "jpeg";
// image/png ISO/IEC 15948:2003 http://www.libpng.org/pub/png/spec/
public static final String IMAGE_PNG = "image/png";
public static final String EXTENSION_PNG = "png";
// image/gif http://www.w3.org/Graphics/GIF/spec-gif89a.txt
public static final String IMAGE_GIF = "image/gif";
public static final String EXTENSION_GIF = "gif";
/**
* TIFF image format.
*
* @see <a href="http://partners.adobe.com/public/developer/tiff/index.html#spec">
* http://partners.adobe.com/public/developer/tiff/index.html#spec</a>
*/
public static final String IMAGE_TIFF = "image/tiff";
public static final String EXTENSION_TIFF = "tiff";
/**
* Pict image format.
*
* @see <a href="http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html">
* http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html</a>
*/
public static final String IMAGE_PICT = "image/pict";
public static final String EXTENSION_PICT = "tiff";
/**
* XML file.
*/
public static final String XML = "text/xml";
public static final String EXTENSION_XML = "xml";
public static String getContentTypeFromFileExtension(String filename) {
String extension = filename.substring(filename.lastIndexOf(".") + 1)
.toLowerCase();
if (extension.equals(EXTENSION_JPG_1)
|| extension.equals(EXTENSION_JPG_2))
return IMAGE_JPEG;
else if (extension.equals(EXTENSION_GIF))
return IMAGE_GIF;
else if (extension.equals(EXTENSION_PICT))
return IMAGE_PICT;
else if (extension.equals(EXTENSION_PNG))
return IMAGE_PNG;
else if (extension.equals(EXTENSION_TIFF))
return IMAGE_TIFF;
else if (extension.equals(EXTENSION_XML))
return XML;
else
return null;
}
}
/* ====================================================================
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.poi.openxml4j.opc;

/**
* Open Packaging Convention content types (see Annex F : Standard Namespaces
* and Content Types).
*
* @author CDubettier define some constants, Julien Chable
*/
public final class ContentTypes {

/*
* Open Packaging Convention (Annex F : Standard Namespaces and Content
* Types)
*/

/**
* Core Properties part.
*/
public static final String CORE_PROPERTIES_PART = "application/vnd.openxmlformats-package.core-properties+xml";

/**
* Digital Signature Certificate part.
*/
public static final String DIGITAL_SIGNATURE_CERTIFICATE_PART = "application/vnd.openxmlformats-package.digital-signature-certificate";

/**
* Digital Signature Origin part.
*/
public static final String DIGITAL_SIGNATURE_ORIGIN_PART = "application/vnd.openxmlformats-package.digital-signature-origin";

/**
* Digital Signature XML Signature part.
*/
public static final String DIGITAL_SIGNATURE_XML_SIGNATURE_PART = "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml";

/**
* Relationships part.
*/
public static final String RELATIONSHIPS_PART = "application/vnd.openxmlformats-package.relationships+xml";

/**
* Custom XML part.
*/
public static final String CUSTOM_XML_PART = "application/vnd.openxmlformats-officedocument.customXmlProperties+xml";

/**
* Plain old xml. Note - OOXML uses application/xml, and not text/xml!
*/
public static final String PLAIN_OLD_XML = "application/xml";

public static final String IMAGE_JPEG = "image/jpeg";

public static final String EXTENSION_JPG_1 = "jpg";

public static final String EXTENSION_JPG_2 = "jpeg";

// image/png ISO/IEC 15948:2003 http://www.libpng.org/pub/png/spec/
public static final String IMAGE_PNG = "image/png";

public static final String EXTENSION_PNG = "png";

// image/gif http://www.w3.org/Graphics/GIF/spec-gif89a.txt
public static final String IMAGE_GIF = "image/gif";

public static final String EXTENSION_GIF = "gif";

/**
* TIFF image format.
*
* @see <a href="http://partners.adobe.com/public/developer/tiff/index.html#spec">
* http://partners.adobe.com/public/developer/tiff/index.html#spec</a>
*/
public static final String IMAGE_TIFF = "image/tiff";

public static final String EXTENSION_TIFF = "tiff";

/**
* Pict image format.
*
* @see <a href="http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html">
* http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html</a>
*/
public static final String IMAGE_PICT = "image/pict";

public static final String EXTENSION_PICT = "tiff";

/**
* XML file.
*/
public static final String XML = "text/xml";

public static final String EXTENSION_XML = "xml";

public static String getContentTypeFromFileExtension(String filename) {
String extension = filename.substring(filename.lastIndexOf(".") + 1)
.toLowerCase();
if (extension.equals(EXTENSION_JPG_1)
|| extension.equals(EXTENSION_JPG_2))
return IMAGE_JPEG;
else if (extension.equals(EXTENSION_GIF))
return IMAGE_GIF;
else if (extension.equals(EXTENSION_PICT))
return IMAGE_PICT;
else if (extension.equals(EXTENSION_PNG))
return IMAGE_PNG;
else if (extension.equals(EXTENSION_TIFF))
return IMAGE_TIFF;
else if (extension.equals(EXTENSION_XML))
return XML;
else
return null;
}
}

+ 29
- 29
src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java View File

@@ -1,29 +1,29 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies the encryption option for parts in a Package.
*
* @author Julien Chable
* @version 0.1
*/
public enum EncryptionOption {
/** No encryption. */
NONE
}
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies the encryption option for parts in a Package.
*
* @author Julien Chable
* @version 0.1
*/
public enum EncryptionOption {
/** No encryption. */
NONE
}

+ 33
- 33
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java View File

@@ -1,33 +1,33 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies package access.
*
* @author Julien Chable
* @version 1.0
*/
public enum PackageAccess {
/** Read only. Write not authorized. */
READ,
/** Write only. Read not authorized. */
WRITE,
/** Read and Write mode. */
READ_WRITE
}
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies package access.
*
* @author Julien Chable
* @version 1.0
*/
public enum PackageAccess {
/** Read only. Write not authorized. */
READ,
/** Write only. Read not authorized. */
WRITE,
/** Read and Write mode. */
READ_WRITE
}

+ 52
- 52
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java View File

@@ -1,52 +1,52 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Open Packaging Convention namespaces URI.
*
* @author Julien Chable
* @version 1.0
*/
public interface PackageNamespaces {
/**
* Content Types.
*/
public static final String CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
/**
* Core Properties.
*/
public static final String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
/**
* Digital Signatures.
*/
public static final String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/digital-signature";
/**
* Relationships.
*/
public static final String RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
/**
* Markup Compatibility.
*/
public static final String MARKUP_COMPATIBILITY = "http://schemas.openxmlformats.org/markup-compatibility/2006";
}
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Open Packaging Convention namespaces URI.
*
* @author Julien Chable
* @version 1.0
*/
public interface PackageNamespaces {
/**
* Content Types.
*/
public static final String CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
/**
* Core Properties.
*/
public static final String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
/**
* Digital Signatures.
*/
public static final String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/digital-signature";
/**
* Relationships.
*/
public static final String RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
/**
* Markup Compatibility.
*/
public static final String MARKUP_COMPATIBILITY = "http://schemas.openxmlformats.org/markup-compatibility/2006";
}

+ 81
- 81
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java View File

@@ -1,81 +1,81 @@
/* ====================================================================
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.poi.openxml4j.opc;
import java.util.ArrayList;
import java.util.TreeMap;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
/**
* A package part collection.
*
* @author Julien Chable
* @version 0.1
*/
public final class PackagePartCollection extends
TreeMap<PackagePartName, PackagePart> {
private static final long serialVersionUID = 2515031135957635515L;
/**
* Arraylist use to store this collection part names as string for rule
* M1.11 optimized checking.
*/
private ArrayList<String> registerPartNameStr = new ArrayList<String>();
@Override
public Object clone() {
return super.clone();
}
/**
* Check rule [M1.11]: a package implementer shall neither create nor
* recognize a part with a part name derived from another part name by
* appending segments to it.
*
* @exception InvalidOperationException
* Throws if you try to add a part with a name derived from
* another part name.
*/
@Override
public PackagePart put(PackagePartName partName, PackagePart part) {
String[] segments = partName.getURI().toASCIIString().split(
PackagingURIHelper.FORWARD_SLASH_STRING);
StringBuffer concatSeg = new StringBuffer();
for (String seg : segments) {
if (!seg.equals(""))
concatSeg.append(PackagingURIHelper.FORWARD_SLASH_CHAR);
concatSeg.append(seg);
if (this.registerPartNameStr.contains(concatSeg.toString())) {
throw new InvalidOperationException(
"You can't add a part with a part name derived from another part ! [M1.11]");
}
}
this.registerPartNameStr.add(partName.getName());
return super.put(partName, part);
}
@Override
public PackagePart remove(Object key) {
if (key instanceof PackagePartName) {
this.registerPartNameStr.remove(((PackagePartName) key).getName());
}
return super.remove(key);
}
}
/* ====================================================================
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.poi.openxml4j.opc;
import java.util.ArrayList;
import java.util.TreeMap;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
/**
* A package part collection.
*
* @author Julien Chable
* @version 0.1
*/
public final class PackagePartCollection extends
TreeMap<PackagePartName, PackagePart> {
private static final long serialVersionUID = 2515031135957635515L;
/**
* Arraylist use to store this collection part names as string for rule
* M1.11 optimized checking.
*/
private ArrayList<String> registerPartNameStr = new ArrayList<String>();
@Override
public Object clone() {
return super.clone();
}
/**
* Check rule [M1.11]: a package implementer shall neither create nor
* recognize a part with a part name derived from another part name by
* appending segments to it.
*
* @exception InvalidOperationException
* Throws if you try to add a part with a name derived from
* another part name.
*/
@Override
public PackagePart put(PackagePartName partName, PackagePart part) {
String[] segments = partName.getURI().toASCIIString().split(
PackagingURIHelper.FORWARD_SLASH_STRING);
StringBuffer concatSeg = new StringBuffer();
for (String seg : segments) {
if (!seg.equals(""))
concatSeg.append(PackagingURIHelper.FORWARD_SLASH_CHAR);
concatSeg.append(seg);
if (this.registerPartNameStr.contains(concatSeg.toString())) {
throw new InvalidOperationException(
"You can't add a part with a part name derived from another part ! [M1.11]");
}
}
this.registerPartNameStr.add(partName.getName());
return super.put(partName, part);
}
@Override
public PackagePart remove(Object key) {
if (key instanceof PackagePartName) {
this.registerPartNameStr.remove(((PackagePartName) key).getName());
}
return super.remove(key);
}
}

+ 506
- 509
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
File diff suppressed because it is too large
View File


+ 77
- 77
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java View File

@@ -1,77 +1,77 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Relationship types.
*
* @author Julien Chable
* @version 0.2
*/
public interface PackageRelationshipTypes {
/**
* Core properties relationship type.
*/
String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
/**
* Digital signature relationship type.
*/
String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
/**
* Digital signature certificate relationship type.
*/
String DIGITAL_SIGNATURE_CERTIFICATE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate";
/**
* Digital signature origin relationship type.
*/
String DIGITAL_SIGNATURE_ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin";
/**
* Thumbnail relationship type.
*/
String THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
/**
* Extended properties relationship type.
*/
String EXTENDED_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
/**
* Core properties relationship type.
*/
String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
/**
* Custom XML relationship type.
*/
String CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
/**
* Image type.
*/
String IMAGE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
/**
* Style type.
*/
String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
}
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Relationship types.
*
* @author Julien Chable
* @version 0.2
*/
public interface PackageRelationshipTypes {
/**
* Core properties relationship type.
*/
String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
/**
* Digital signature relationship type.
*/
String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
/**
* Digital signature certificate relationship type.
*/
String DIGITAL_SIGNATURE_CERTIFICATE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate";
/**
* Digital signature origin relationship type.
*/
String DIGITAL_SIGNATURE_ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin";
/**
* Thumbnail relationship type.
*/
String THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
/**
* Extended properties relationship type.
*/
String EXTENDED_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
/**
* Core properties relationship type.
*/
String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
/**
* Custom XML relationship type.
*/
String CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
/**
* Image type.
*/
String IMAGE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
/**
* Style type.
*/
String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
}

+ 622
- 622
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java
File diff suppressed because it is too large
View File


+ 77
- 77
src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java View File

@@ -1,77 +1,77 @@
/* ====================================================================
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.poi.openxml4j.opc;
import java.io.InputStream;
import java.io.OutputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public final class StreamHelper {
private StreamHelper() {
// Do nothing
}
/**
* Turning the DOM4j object in the specified output stream.
*
* @param xmlContent
* The XML document.
* @param outStream
* The OutputStream in which the XML document will be written.
* @return <b>true</b> if the xml is successfully written in the stream,
* else <b>false</b>.
*/
public static boolean saveXmlInStream(Document xmlContent,
OutputStream outStream) {
try {
OutputFormat outformat = OutputFormat.createPrettyPrint();
outformat.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(outStream, outformat);
writer.write(xmlContent);
} catch (Exception e) {
return false;
}
return true;
}
/**
* Copy the input stream into the output stream.
*
* @param inStream
* The source stream.
* @param outStream
* The destination stream.
* @return <b>true</b> if the operation succeed, else return <b>false</b>.
*/
public static boolean copyStream(InputStream inStream, OutputStream outStream) {
try {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) >= 0) {
outStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
return false;
}
return true;
}
}
/* ====================================================================
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.poi.openxml4j.opc;
import java.io.InputStream;
import java.io.OutputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public final class StreamHelper {
private StreamHelper() {
// Do nothing
}
/**
* Turning the DOM4j object in the specified output stream.
*
* @param xmlContent
* The XML document.
* @param outStream
* The OutputStream in which the XML document will be written.
* @return <b>true</b> if the xml is successfully written in the stream,
* else <b>false</b>.
*/
public static boolean saveXmlInStream(Document xmlContent,
OutputStream outStream) {
try {
OutputFormat outformat = OutputFormat.createPrettyPrint();
outformat.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(outStream, outformat);
writer.write(xmlContent);
} catch (Exception e) {
return false;
}
return true;
}
/**
* Copy the input stream into the output stream.
*
* @param inStream
* The source stream.
* @param outStream
* The destination stream.
* @return <b>true</b> if the operation succeed, else return <b>false</b>.
*/
public static boolean copyStream(InputStream inStream, OutputStream outStream) {
try {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) >= 0) {
outStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
return false;
}
return true;
}
}

+ 32
- 32
src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java View File

@@ -1,32 +1,32 @@
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies whether the target of a PackageRelationship is inside or outside a
* Package.
*
* @author Julien Chable
* @version 1.0
*/
public enum TargetMode {
/** The relationship references a resource that is external to the package. */
INTERNAL,
/** The relationship references a part that is inside the package. */
EXTERNAL
}
/* ====================================================================
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.poi.openxml4j.opc;
/**
* Specifies whether the target of a PackageRelationship is inside or outside a
* Package.
*
* @author Julien Chable
* @version 1.0
*/
public enum TargetMode {
/** The relationship references a resource that is external to the package. */
INTERNAL,
/** The relationship references a part that is inside the package. */
EXTERNAL
}

+ 460
- 465
src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java View File

@@ -1,465 +1,460 @@
/* ====================================================================
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.poi.openxml4j.opc;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.FileHelper;
import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller;
import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;
import org.apache.poi.openxml4j.util.ZipEntrySource;
import org.apache.poi.openxml4j.util.ZipFileZipEntrySource;
import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
/**
* Physical zip package.
*
* @author Julien Chable
* @version 0.2
*/
public final class ZipPackage extends Package {
private static POILogger logger = POILogFactory.getLogger(ZipPackage.class);
/**
* Zip archive, as either a file on disk,
* or a stream
*/
private final ZipEntrySource zipArchive;
/**
* Constructor. Creates a new ZipPackage.
*/
public ZipPackage() {
super(defaultPackageAccess);
this.zipArchive = null;
}
/**
* Constructor. <b>Operation not supported.</b>
*
* @param in
* Zip input stream to load.
* @param access
* @throws IllegalArgumentException
* If the specified input stream not an instance of
* ZipInputStream.
*/
ZipPackage(InputStream in, PackageAccess access) throws IOException {
super(access);
this.zipArchive = new ZipInputStreamZipEntrySource(
new ZipInputStream(in)
);
}
/**
* Constructor. Opens a Zip based Open XML document.
*
* @param path
* The path of the file to open or create.
* @param access
* The package access mode.
* @throws InvalidFormatException
* If the content type part parsing encounters an error.
*/
ZipPackage(String path, PackageAccess access) throws InvalidFormatException {
super(access);
ZipFile zipFile = ZipHelper.openZipFile(path);
if (zipFile == null)
throw new InvalidOperationException(
"Can't open the specified file: '" + path + "'");
this.zipArchive = new ZipFileZipEntrySource(zipFile);
}
/**
* Retrieves the parts from this package. We assume that the package has not
* been yet inspect to retrieve all the parts, this method will open the
* archive and look for all parts contain inside it. If the package part
* list is not empty, it will be emptied.
*
* @return All parts contain in this package.
* @throws InvalidFormatException
* Throws if the package is not valid.
*/
@Override
protected PackagePart[] getPartsImpl() throws InvalidFormatException {
if (this.partList == null) {
// The package has just been created, we create an empty part
// list.
this.partList = new PackagePartCollection();
}
if (this.zipArchive == null) {
return this.partList.values().toArray(
new PackagePart[this.partList.values().size()]);
} else {
// First we need to parse the content type part
Enumeration<? extends ZipEntry> entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.getName().equals(
ContentTypeManager.CONTENT_TYPES_PART_NAME)) {
try {
this.contentTypeManager = new ZipContentTypeManager(
getZipArchive().getInputStream(entry), this);
} catch (IOException e) {
throw new InvalidFormatException(e.getMessage());
}
break;
}
}
// At this point, we should have loaded the content type part
if (this.contentTypeManager == null) {
throw new InvalidFormatException(
"Package should contain a content type part [M1.13]");
}
// Now create all the relationships
// (Need to create relationships before other
// parts, otherwise we might create a part before
// its relationship exists, and then it won't tie up)
entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
PackagePartName partName = buildPartName(entry);
if(partName == null) continue;
// Only proceed for Relationships at this stage
String contentType = contentTypeManager.getContentType(partName);
if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) {
try {
partList.put(partName, new ZipPackagePart(this, entry,
partName, contentType));
} catch (InvalidOperationException e) {
throw new InvalidFormatException(e.getMessage());
}
}
}
// Then we can go through all the other parts
entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
PackagePartName partName = buildPartName(entry);
if(partName == null) continue;
String contentType = contentTypeManager
.getContentType(partName);
if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) {
// Already handled
}
else if (contentType != null) {
try {
partList.put(partName, new ZipPackagePart(this, entry,
partName, contentType));
} catch (InvalidOperationException e) {
throw new InvalidFormatException(e.getMessage());
}
} else {
throw new InvalidFormatException(
"The part "
+ partName.getURI().getPath()
+ " does not have any content type ! Rule: Package require content types when retrieving a part from a package. [M.1.14]");
}
}
return (ZipPackagePart[]) partList.values().toArray(
new ZipPackagePart[partList.size()]);
}
}
/**
* Builds a PackagePartName for the given ZipEntry,
* or null if it's the content types / invalid part
*/
private PackagePartName buildPartName(ZipEntry entry) {
try {
// We get an error when we parse [Content_Types].xml
// because it's not a valid URI.
if (entry.getName().equals(
ContentTypeManager.CONTENT_TYPES_PART_NAME)) {
return null;
} else {
return PackagingURIHelper.createPartName(ZipHelper
.getOPCNameFromZipItemName(entry.getName()));
}
} catch (Exception e) {
// We assume we can continue, even in degraded mode ...
logger.log(POILogger.WARN,"Entry "
+ entry.getName()
+ " is not valid, so this part won't be add to the package.");
return null;
}
}
/**
* Create a new MemoryPackagePart from the specified URI and content type
*
*
* aram partName The part URI.
*
* @param contentType
* The part content type.
* @return The newly created zip package part, else <b>null</b>.
*/
@Override
protected PackagePart createPartImpl(PackagePartName partName,
String contentType, boolean loadRelationships) {
if (contentType == null)
throw new IllegalArgumentException("contentType");
if (partName == null)
throw new IllegalArgumentException("partName");
try {
return new MemoryPackagePart(this, partName, contentType,
loadRelationships);
} catch (InvalidFormatException e) {
// TODO - don't use system.err. Is it valid to return null when this exception occurs?
System.err.println(e);
return null;
}
}
/**
* Delete a part from the package
*
* @throws IllegalArgumentException
* Throws if the part URI is nulll or invalid.
*/
@Override
protected void removePartImpl(PackagePartName partName) {
if (partName == null)
throw new IllegalArgumentException("partUri");
}
/**
* Flush the package. Do nothing.
*/
@Override
protected void flushImpl() {
// Do nothing
}
/**
* Close and save the package.
*
* @see #close()
*/
@Override
protected void closeImpl() throws IOException {
// Flush the package
flush();
// Save the content
if (this.originalPackagePath != null
&& !"".equals(this.originalPackagePath)) {
File targetFile = new File(this.originalPackagePath);
if (targetFile.exists()) {
// Case of a package previously open
File tempFile = File.createTempFile(
generateTempFileName(FileHelper
.getDirectory(targetFile)), ".tmp");
// Save the final package to a temporary file
try {
save(tempFile);
this.zipArchive.close(); // Close the zip archive to be
// able to delete it
FileHelper.copyFile(tempFile, targetFile);
} finally {
// Either the save operation succeed or not, we delete the
// temporary file
if (!tempFile.delete()) {
logger
.log(POILogger.WARN,"The temporary file: '"
+ targetFile.getAbsolutePath()
+ "' cannot be deleted ! Make sure that no other application use it.");
}
}
} else {
throw new InvalidOperationException(
"Can't close a package not previously open with the open() method !");
}
}
}
/**
* Create a unique identifier to be use as a temp file name.
*
* @return A unique identifier use to be use as a temp file name.
*/
private synchronized String generateTempFileName(File directory) {
File tmpFilename;
do {
tmpFilename = new File(directory.getAbsoluteFile() + File.separator
+ "OpenXML4J" + System.nanoTime());
} while (tmpFilename.exists());
return FileHelper.getFilename(tmpFilename.getAbsoluteFile());
}
/**
* Close the package without saving the document. Discard all the changes
* made to this package.
*/
@Override
protected void revertImpl() {
try {
if (this.zipArchive != null)
this.zipArchive.close();
} catch (IOException e) {
// Do nothing, user dont have to know
}
}
/**
* Implement the getPart() method to retrieve a part from its URI in the
* current package
*
*
* @see #getPart(PackageRelationship)
*/
@Override
protected PackagePart getPartImpl(PackagePartName partName) {
if (partList.containsKey(partName)) {
return partList.get(partName);
}
return null;
}
/**
* Save this package into the specified stream
*
*
* @param outputStream
* The stream use to save this package.
*
* @see #save(OutputStream)
*/
@Override
public void saveImpl(OutputStream outputStream) {
// Check that the document was open in write mode
throwExceptionIfReadOnly();
ZipOutputStream zos = null;
try {
if (!(outputStream instanceof ZipOutputStream))
zos = new ZipOutputStream(outputStream);
else
zos = (ZipOutputStream) outputStream;
// If the core properties part does not exist in the part list,
// we save it as well
if (this.getPartsByRelationshipType(
PackageRelationshipTypes.CORE_PROPERTIES).size() == 0) {
logger.log(POILogger.DEBUG,"Save core properties part");
// We have to save the core properties part ...
new ZipPackagePropertiesMarshaller().marshall(
this.packageProperties, zos);
// ... and to add its relationship ...
this.relationships.addRelationship(this.packageProperties
.getPartName().getURI(), TargetMode.INTERNAL,
PackageRelationshipTypes.CORE_PROPERTIES, null);
// ... and the content if it has not been added yet.
if (!this.contentTypeManager
.isContentTypeRegister(ContentTypes.CORE_PROPERTIES_PART)) {
this.contentTypeManager.addContentType(
this.packageProperties.getPartName(),
ContentTypes.CORE_PROPERTIES_PART);
}
}
// Save package relationships part.
logger.log(POILogger.DEBUG,"Save package relationships");
ZipPartMarshaller.marshallRelationshipPart(this.getRelationships(),
PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME,
zos);
// Save content type part.
logger.log(POILogger.DEBUG,"Save content types part");
this.contentTypeManager.save(zos);
// Save parts.
for (PackagePart part : getParts()) {
// If the part is a relationship part, we don't save it, it's
// the source part that will do the job.
if (part.isRelationshipPart())
continue;
logger.log(POILogger.DEBUG,"Save part '"
+ ZipHelper.getZipItemNameFromOPCName(part
.getPartName().getName()) + "'");
PartMarshaller marshaller = partMarshallers
.get(part.contentType);
if (marshaller != null) {
if (!marshaller.marshall(part, zos)) {
throw new OpenXML4JException(
"The part "
+ part.getPartName().getURI()
+ " fail to be saved in the stream with marshaller "
+ marshaller);
}
} else {
if (!defaultPartMarshaller.marshall(part, zos))
throw new OpenXML4JException(
"The part "
+ part.getPartName().getURI()
+ " fail to be saved in the stream with marshaller "
+ defaultPartMarshaller);
}
}
zos.close();
} catch (Exception e) {
logger
.log(POILogger.ERROR,"Fail to save: an error occurs while saving the package : "
+ e.getMessage());
}
}
/**
* Get the zip archive
*
* @return The zip archive.
*/
public ZipEntrySource getZipArchive() {
return zipArchive;
}
}
/* ====================================================================
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.poi.openxml4j.opc;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.FileHelper;
import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller;
import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;
import org.apache.poi.openxml4j.util.ZipEntrySource;
import org.apache.poi.openxml4j.util.ZipFileZipEntrySource;
import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;

/**
* Physical zip package.
*
* @author Julien Chable
*/
public final class ZipPackage extends Package {

private static POILogger logger = POILogFactory.getLogger(ZipPackage.class);

/**
* Zip archive, as either a file on disk,
* or a stream
*/
private final ZipEntrySource zipArchive;

/**
* Constructor. Creates a new ZipPackage.
*/
public ZipPackage() {
super(defaultPackageAccess);
this.zipArchive = null;
}

/**
* Constructor. <b>Operation not supported.</b>
*
* @param in
* Zip input stream to load.
* @param access
* @throws IllegalArgumentException
* If the specified input stream not an instance of
* ZipInputStream.
*/
ZipPackage(InputStream in, PackageAccess access) throws IOException {
super(access);
this.zipArchive = new ZipInputStreamZipEntrySource(
new ZipInputStream(in)
);
}

/**
* Constructor. Opens a Zip based Open XML document.
*
* @param path
* The path of the file to open or create.
* @param access
* The package access mode.
* @throws InvalidFormatException
* If the content type part parsing encounters an error.
*/
ZipPackage(String path, PackageAccess access) throws InvalidFormatException {
super(access);

ZipFile zipFile = ZipHelper.openZipFile(path);
if (zipFile == null)
throw new InvalidOperationException(
"Can't open the specified file: '" + path + "'");
this.zipArchive = new ZipFileZipEntrySource(zipFile);
}

/**
* Retrieves the parts from this package. We assume that the package has not
* been yet inspect to retrieve all the parts, this method will open the
* archive and look for all parts contain inside it. If the package part
* list is not empty, it will be emptied.
*
* @return All parts contain in this package.
* @throws InvalidFormatException
* Throws if the package is not valid.
*/
@Override
protected PackagePart[] getPartsImpl() throws InvalidFormatException {
if (this.partList == null) {
// The package has just been created, we create an empty part
// list.
this.partList = new PackagePartCollection();
}

if (this.zipArchive == null) {
return this.partList.values().toArray(
new PackagePart[this.partList.values().size()]);
}
// First we need to parse the content type part
Enumeration<? extends ZipEntry> entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.getName().equals(
ContentTypeManager.CONTENT_TYPES_PART_NAME)) {
try {
this.contentTypeManager = new ZipContentTypeManager(
getZipArchive().getInputStream(entry), this);
} catch (IOException e) {
throw new InvalidFormatException(e.getMessage());
}
break;
}
}

// At this point, we should have loaded the content type part
if (this.contentTypeManager == null) {
throw new InvalidFormatException(
"Package should contain a content type part [M1.13]");
}

// Now create all the relationships
// (Need to create relationships before other
// parts, otherwise we might create a part before
// its relationship exists, and then it won't tie up)
entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
PackagePartName partName = buildPartName(entry);
if(partName == null) continue;

// Only proceed for Relationships at this stage
String contentType = contentTypeManager.getContentType(partName);
if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) {
try {
partList.put(partName, new ZipPackagePart(this, entry,
partName, contentType));
} catch (InvalidOperationException e) {
throw new InvalidFormatException(e.getMessage());
}
}
}

// Then we can go through all the other parts
entries = this.zipArchive.getEntries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
PackagePartName partName = buildPartName(entry);
if(partName == null) continue;

String contentType = contentTypeManager
.getContentType(partName);
if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) {
// Already handled
}
else if (contentType != null) {
try {
partList.put(partName, new ZipPackagePart(this, entry,
partName, contentType));
} catch (InvalidOperationException e) {
throw new InvalidFormatException(e.getMessage());
}
} else {
throw new InvalidFormatException(
"The part "
+ partName.getURI().getPath()
+ " does not have any content type ! Rule: Package require content types when retrieving a part from a package. [M.1.14]");
}
}

return partList.values().toArray(new ZipPackagePart[partList.size()]);
}

/**
* Builds a PackagePartName for the given ZipEntry,
* or null if it's the content types / invalid part
*/
private PackagePartName buildPartName(ZipEntry entry) {
try {
// We get an error when we parse [Content_Types].xml
// because it's not a valid URI.
if (entry.getName().equals(
ContentTypeManager.CONTENT_TYPES_PART_NAME)) {
return null;
}
return PackagingURIHelper.createPartName(ZipHelper
.getOPCNameFromZipItemName(entry.getName()));
} catch (Exception e) {
// We assume we can continue, even in degraded mode ...
logger.log(POILogger.WARN,"Entry "
+ entry.getName()
+ " is not valid, so this part won't be add to the package.");
return null;
}
}

/**
* Create a new MemoryPackagePart from the specified URI and content type
*
*
* aram partName The part URI.
*
* @param contentType
* The part content type.
* @return The newly created zip package part, else <b>null</b>.
*/
@Override
protected PackagePart createPartImpl(PackagePartName partName,
String contentType, boolean loadRelationships) {
if (contentType == null)
throw new IllegalArgumentException("contentType");

if (partName == null)
throw new IllegalArgumentException("partName");

try {
return new MemoryPackagePart(this, partName, contentType,
loadRelationships);
} catch (InvalidFormatException e) {
// TODO - don't use system.err. Is it valid to return null when this exception occurs?
System.err.println(e);
return null;
}
}

/**
* Delete a part from the package
*
* @throws IllegalArgumentException
* Throws if the part URI is nulll or invalid.
*/
@Override
protected void removePartImpl(PackagePartName partName) {
if (partName == null)
throw new IllegalArgumentException("partUri");
}

/**
* Flush the package. Do nothing.
*/
@Override
protected void flushImpl() {
// Do nothing
}

/**
* Close and save the package.
*
* @see #close()
*/
@Override
protected void closeImpl() throws IOException {
// Flush the package
flush();

// Save the content
if (this.originalPackagePath != null
&& !"".equals(this.originalPackagePath)) {
File targetFile = new File(this.originalPackagePath);
if (targetFile.exists()) {
// Case of a package previously open

File tempFile = File.createTempFile(
generateTempFileName(FileHelper
.getDirectory(targetFile)), ".tmp");

// Save the final package to a temporary file
try {
save(tempFile);
this.zipArchive.close(); // Close the zip archive to be
// able to delete it
FileHelper.copyFile(tempFile, targetFile);
} finally {
// Either the save operation succeed or not, we delete the
// temporary file
if (!tempFile.delete()) {
logger
.log(POILogger.WARN,"The temporary file: '"
+ targetFile.getAbsolutePath()
+ "' cannot be deleted ! Make sure that no other application use it.");
}
}
} else {
throw new InvalidOperationException(
"Can't close a package not previously open with the open() method !");
}
}
}

/**
* Create a unique identifier to be use as a temp file name.
*
* @return A unique identifier use to be use as a temp file name.
*/
private synchronized String generateTempFileName(File directory) {
File tmpFilename;
do {
tmpFilename = new File(directory.getAbsoluteFile() + File.separator
+ "OpenXML4J" + System.nanoTime());
} while (tmpFilename.exists());
return FileHelper.getFilename(tmpFilename.getAbsoluteFile());
}

/**
* Close the package without saving the document. Discard all the changes
* made to this package.
*/
@Override
protected void revertImpl() {
try {
if (this.zipArchive != null)
this.zipArchive.close();
} catch (IOException e) {
// Do nothing, user dont have to know
}
}

/**
* Implement the getPart() method to retrieve a part from its URI in the
* current package
*
*
* @see #getPart(PackageRelationship)
*/
@Override
protected PackagePart getPartImpl(PackagePartName partName) {
if (partList.containsKey(partName)) {
return partList.get(partName);
}
return null;
}

/**
* Save this package into the specified stream
*
*
* @param outputStream
* The stream use to save this package.
*
* @see #save(OutputStream)
*/
@Override
public void saveImpl(OutputStream outputStream) {
// Check that the document was open in write mode
throwExceptionIfReadOnly();
ZipOutputStream zos = null;

try {
if (!(outputStream instanceof ZipOutputStream))
zos = new ZipOutputStream(outputStream);
else
zos = (ZipOutputStream) outputStream;

// If the core properties part does not exist in the part list,
// we save it as well
if (this.getPartsByRelationshipType(
PackageRelationshipTypes.CORE_PROPERTIES).size() == 0) {
logger.log(POILogger.DEBUG,"Save core properties part");

// We have to save the core properties part ...
new ZipPackagePropertiesMarshaller().marshall(
this.packageProperties, zos);
// ... and to add its relationship ...
this.relationships.addRelationship(this.packageProperties
.getPartName().getURI(), TargetMode.INTERNAL,
PackageRelationshipTypes.CORE_PROPERTIES, null);
// ... and the content if it has not been added yet.
if (!this.contentTypeManager
.isContentTypeRegister(ContentTypes.CORE_PROPERTIES_PART)) {
this.contentTypeManager.addContentType(
this.packageProperties.getPartName(),
ContentTypes.CORE_PROPERTIES_PART);
}
}

// Save package relationships part.
logger.log(POILogger.DEBUG,"Save package relationships");
ZipPartMarshaller.marshallRelationshipPart(this.getRelationships(),
PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME,
zos);

// Save content type part.
logger.log(POILogger.DEBUG,"Save content types part");
this.contentTypeManager.save(zos);

// Save parts.
for (PackagePart part : getParts()) {
// If the part is a relationship part, we don't save it, it's
// the source part that will do the job.
if (part.isRelationshipPart())
continue;

logger.log(POILogger.DEBUG,"Save part '"
+ ZipHelper.getZipItemNameFromOPCName(part
.getPartName().getName()) + "'");
PartMarshaller marshaller = partMarshallers
.get(part.contentType);
if (marshaller != null) {
if (!marshaller.marshall(part, zos)) {
throw new OpenXML4JException(
"The part "
+ part.getPartName().getURI()
+ " fail to be saved in the stream with marshaller "
+ marshaller);
}
} else {
if (!defaultPartMarshaller.marshall(part, zos))
throw new OpenXML4JException(
"The part "
+ part.getPartName().getURI()
+ " fail to be saved in the stream with marshaller "
+ defaultPartMarshaller);
}
}
zos.close();
} catch (Exception e) {
logger
.log(POILogger.ERROR,"Fail to save: an error occurs while saving the package : "
+ e.getMessage());
}
}

/**
* Get the zip archive
*
* @return The zip archive.
*/
public ZipEntrySource getZipArchive() {
return zipArchive;
}
}

+ 224
- 224
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java View File

@@ -1,224 +1,224 @@
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
/**
* Represents a immutable MIME ContentType value (RFC 2616 &#167;3.7)
* <p>
* media-type = type "/" subtype *( ";" parameter ) type = token<br>
* subtype = token<br>
* </p><p>
* Rule M1.13 : Package implementers shall only create and only recognize parts
* with a content type; format designers shall specify a content type for each
* part included in the format. Content types for package parts shall fit the
* definition and syntax for media types as specified in RFC 2616, \&#167;3.7.
* </p><p>
* Rule M1.14: Content types shall not use linear white space either between the
* type and subtype or between an attribute and its value. Content types also
* shall not have leading or trailing white spaces. Package implementers shall
* create only such content types and shall require such content types when
* retrieving a part from a package; format designers shall specify only such
* content types for inclusion in the format.
* </p>
* @author Julien Chable
* @version 0.1
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">http://www.ietf.org/rfc/rfc2045.txt</a>
* @see <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
*/
public final class ContentType {
/**
* Type in Type/Subtype.
*/
private String type;
/**
* Subtype
*/
private String subType;
/**
* Parameters
*/
private Hashtable<String, String> parameters;
/**
* Media type compiled pattern for parameters.
*/
private final static Pattern patternMediaType;
static {
/*
* token = 1*<any CHAR except CTLs or separators>
*
* separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" |
* <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
*
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
*
* CHAR = <any US-ASCII character (octets 0 - 127)>
*/
String token = "[\\x21-\\x7E&&[^\\(\\)<>@,;:\\\\/\"\\[\\]\\?={}\\x20\\x09]]";
/*
* parameter = attribute "=" value
*
* attribute = token
*
* value = token | quoted-string
*/
// Keep for future use with parameter:
// String parameter = "(" + token + "+)=(\"?" + token + "+\"?)";
/*
* Pattern for media type.
*
* Don't allow comment, rule M1.15: The package implementer shall
* require a content type that does not include comments and the format
* designer shall specify such a content type.
*
* comment = "(" *( ctext | quoted-pair | comment ) ")"
*
* ctext = <any TEXT excluding "(" and ")">
*
* TEXT = <any OCTET except CTLs, but including LWS>
*
* LWS = [CRLF] 1*( SP | HT )
*
* CR = <US-ASCII CR, carriage return (13)>
*
* LF = <US-ASCII LF, linefeed (10)>
*
* SP = <US-ASCII SP, space (32)>
*
* HT = <US-ASCII HT, horizontal-tab (9)>
*
* quoted-pair = "\" CHAR
*/
// Keep for future use with parameter:
// patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
// + "+)(;" + parameter + ")*$");
patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
+ "+)$");
}
/**
* Constructor. Check the input with the RFC 2616 grammar.
*
* @param contentType
* The content type to store.
* @throws InvalidFormatException
* If the specified content type is not valid with RFC 2616.
*/
public ContentType(String contentType) throws InvalidFormatException {
// Conversion en US-ASCII
String contentTypeASCII = null;
try {
contentTypeASCII = new String(contentType.getBytes(), "US-ASCII");
} catch (UnsupportedEncodingException e) {
throw new InvalidFormatException(
"The specified content type is not an ASCII value.");
}
Matcher mMediaType = patternMediaType.matcher(contentTypeASCII);
if (!mMediaType.matches())
throw new InvalidFormatException(
"The specified content type '"
+ contentType
+ "' is not compliant with RFC 2616: malformed content type.");
// Type/subtype
if (mMediaType.groupCount() >= 2) {
this.type = mMediaType.group(1);
this.subType = mMediaType.group(2);
// Parameters
this.parameters = new Hashtable<String, String>(1);
for (int i = 4; i <= mMediaType.groupCount()
&& (mMediaType.group(i) != null); i += 2) {
this.parameters.put(mMediaType.group(i), mMediaType
.group(i + 1));
}
}
}
@Override
public final String toString() {
StringBuffer retVal = new StringBuffer();
retVal.append(this.getType());
retVal.append("/");
retVal.append(this.getSubType());
// Keep for future implementation if needed
// for (String key : parameters.keySet()) {
// retVal.append(";");
// retVal.append(key);
// retVal.append("=");
// retVal.append(parameters.get(key));
// }
return retVal.toString();
}
@Override
public boolean equals(Object obj) {
return (!(obj instanceof ContentType))
|| (this.toString().equalsIgnoreCase(obj.toString()));
}
@Override
public int hashCode() {
return this.toString().hashCode();
}
/* Getters */
/**
* Get the subtype.
*
* @return The subtype of this content type.
*/
public String getSubType() {
return this.subType;
}
/**
* Get the type.
*
* @return The type of this content type.
*/
public String getType() {
return this.type;
}
/**
* Gets the value associated to the specified key.
*
* @param key
* The key of the key/value pair.
* @return The value associated to the specified key.
*/
public String getParameters(String key) {
return parameters.get(key);
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
/**
* Represents a immutable MIME ContentType value (RFC 2616 &#167;3.7)
* <p>
* media-type = type "/" subtype *( ";" parameter ) type = token<br>
* subtype = token<br>
* </p><p>
* Rule M1.13 : Package implementers shall only create and only recognize parts
* with a content type; format designers shall specify a content type for each
* part included in the format. Content types for package parts shall fit the
* definition and syntax for media types as specified in RFC 2616, \&#167;3.7.
* </p><p>
* Rule M1.14: Content types shall not use linear white space either between the
* type and subtype or between an attribute and its value. Content types also
* shall not have leading or trailing white spaces. Package implementers shall
* create only such content types and shall require such content types when
* retrieving a part from a package; format designers shall specify only such
* content types for inclusion in the format.
* </p>
* @author Julien Chable
* @version 0.1
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">http://www.ietf.org/rfc/rfc2045.txt</a>
* @see <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
*/
public final class ContentType {
/**
* Type in Type/Subtype.
*/
private String type;
/**
* Subtype
*/
private String subType;
/**
* Parameters
*/
private Hashtable<String, String> parameters;
/**
* Media type compiled pattern for parameters.
*/
private final static Pattern patternMediaType;
static {
/*
* token = 1*<any CHAR except CTLs or separators>
*
* separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" |
* <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
*
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
*
* CHAR = <any US-ASCII character (octets 0 - 127)>
*/
String token = "[\\x21-\\x7E&&[^\\(\\)<>@,;:\\\\/\"\\[\\]\\?={}\\x20\\x09]]";
/*
* parameter = attribute "=" value
*
* attribute = token
*
* value = token | quoted-string
*/
// Keep for future use with parameter:
// String parameter = "(" + token + "+)=(\"?" + token + "+\"?)";
/*
* Pattern for media type.
*
* Don't allow comment, rule M1.15: The package implementer shall
* require a content type that does not include comments and the format
* designer shall specify such a content type.
*
* comment = "(" *( ctext | quoted-pair | comment ) ")"
*
* ctext = <any TEXT excluding "(" and ")">
*
* TEXT = <any OCTET except CTLs, but including LWS>
*
* LWS = [CRLF] 1*( SP | HT )
*
* CR = <US-ASCII CR, carriage return (13)>
*
* LF = <US-ASCII LF, linefeed (10)>
*
* SP = <US-ASCII SP, space (32)>
*
* HT = <US-ASCII HT, horizontal-tab (9)>
*
* quoted-pair = "\" CHAR
*/
// Keep for future use with parameter:
// patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
// + "+)(;" + parameter + ")*$");
patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
+ "+)$");
}
/**
* Constructor. Check the input with the RFC 2616 grammar.
*
* @param contentType
* The content type to store.
* @throws InvalidFormatException
* If the specified content type is not valid with RFC 2616.
*/
public ContentType(String contentType) throws InvalidFormatException {
// Conversion en US-ASCII
String contentTypeASCII = null;
try {
contentTypeASCII = new String(contentType.getBytes(), "US-ASCII");
} catch (UnsupportedEncodingException e) {
throw new InvalidFormatException(
"The specified content type is not an ASCII value.");
}
Matcher mMediaType = patternMediaType.matcher(contentTypeASCII);
if (!mMediaType.matches())
throw new InvalidFormatException(
"The specified content type '"
+ contentType
+ "' is not compliant with RFC 2616: malformed content type.");
// Type/subtype
if (mMediaType.groupCount() >= 2) {
this.type = mMediaType.group(1);
this.subType = mMediaType.group(2);
// Parameters
this.parameters = new Hashtable<String, String>(1);
for (int i = 4; i <= mMediaType.groupCount()
&& (mMediaType.group(i) != null); i += 2) {
this.parameters.put(mMediaType.group(i), mMediaType
.group(i + 1));
}
}
}
@Override
public final String toString() {
StringBuffer retVal = new StringBuffer();
retVal.append(this.getType());
retVal.append("/");
retVal.append(this.getSubType());
// Keep for future implementation if needed
// for (String key : parameters.keySet()) {
// retVal.append(";");
// retVal.append(key);
// retVal.append("=");
// retVal.append(parameters.get(key));
// }
return retVal.toString();
}
@Override
public boolean equals(Object obj) {
return (!(obj instanceof ContentType))
|| (this.toString().equalsIgnoreCase(obj.toString()));
}
@Override
public int hashCode() {
return this.toString().hashCode();
}
/* Getters */
/**
* Get the subtype.
*
* @return The subtype of this content type.
*/
public String getSubType() {
return this.subType;
}
/**
* Get the type.
*
* @return The type of this content type.
*/
public String getType() {
return this.type;
}
/**
* Gets the value associated to the specified key.
*
* @param key
* The key of the key/value pair.
* @return The value associated to the specified key.
*/
public String getParameters(String key) {
return parameters.get(key);
}
}

+ 91
- 91
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java View File

@@ -1,91 +1,91 @@
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
/**
* Provide useful method to manage file.
*
* @author Julien Chable
* @version 0.1
*/
public final class FileHelper {
/**
* Get the directory part of the specified file path.
*
* @param f
* File to process.
* @return The directory path from the specified
*/
public static File getDirectory(File f) {
if (f != null) {
String path = f.getPath();
int len = path.length();
int num2 = len;
while (--num2 >= 0) {
char ch1 = path.charAt(num2);
if (ch1 == File.separatorChar) {
return new File(path.substring(0, num2));
}
}
}
return null;
}
/**
* Copy a file.
*
* @param in
* The source file.
* @param out
* The target location.
* @throws IOException
* If an I/O error occur.
*/
public static void copyFile(File in, File out) throws IOException {
FileChannel sourceChannel = new FileInputStream(in).getChannel();
FileChannel destinationChannel = new FileOutputStream(out).getChannel();
sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
sourceChannel.close();
destinationChannel.close();
}
/**
* Get file name from the specified File object.
*/
public static String getFilename(File file) {
if (file != null) {
String path = file.getPath();
int len = path.length();
int num2 = len;
while (--num2 >= 0) {
char ch1 = path.charAt(num2);
if (ch1 == File.separatorChar)
return path.substring(num2 + 1, len);
}
}
return "";
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
/**
* Provide useful method to manage file.
*
* @author Julien Chable
* @version 0.1
*/
public final class FileHelper {
/**
* Get the directory part of the specified file path.
*
* @param f
* File to process.
* @return The directory path from the specified
*/
public static File getDirectory(File f) {
if (f != null) {
String path = f.getPath();
int len = path.length();
int num2 = len;
while (--num2 >= 0) {
char ch1 = path.charAt(num2);
if (ch1 == File.separatorChar) {
return new File(path.substring(0, num2));
}
}
}
return null;
}
/**
* Copy a file.
*
* @param in
* The source file.
* @param out
* The target location.
* @throws IOException
* If an I/O error occur.
*/
public static void copyFile(File in, File out) throws IOException {
FileChannel sourceChannel = new FileInputStream(in).getChannel();
FileChannel destinationChannel = new FileOutputStream(out).getChannel();
sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
sourceChannel.close();
destinationChannel.close();
}
/**
* Get file name from the specified File object.
*/
public static String getFilename(File file) {
if (file != null) {
String path = file.getPath();
int len = path.length();
int num2 = len;
while (--num2 >= 0) {
char ch1 = path.charAt(num2);
if (ch1 == File.separatorChar)
return path.substring(num2 + 1, len);
}
}
return "";
}
}

+ 96
- 96
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java View File

@@ -1,96 +1,96 @@
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Build an output stream for MemoryPackagePart.
*
* @author Julien Chable
* @version 1.0
*/
public final class MemoryPackagePartOutputStream extends OutputStream {
private MemoryPackagePart part;
private ByteArrayOutputStream buff;
public MemoryPackagePartOutputStream(MemoryPackagePart part) {
this.part = part;
buff = new ByteArrayOutputStream();
}
@Override
public void write(int b) throws IOException {
buff.write(b);
}
/**
* Close this stream and flush the content.
* @see #flush()
*/
@Override
public void close() throws IOException {
this.flush();
}
/**
* Flush this output stream. This method is called by the close() method.
* Warning : don't call this method for output consistency.
* @see #close()
*/
@Override
public void flush() throws IOException {
buff.flush();
if (part.data != null) {
byte[] newArray = new byte[part.data.length + buff.size()];
// copy the previous contents of part.data in newArray
System.arraycopy(part.data, 0, newArray, 0, part.data.length);
// append the newly added data
byte[] buffArr = buff.toByteArray();
System.arraycopy(buffArr, 0, newArray, part.data.length,
buffArr.length);
// save the result as new data
part.data = newArray;
} else {
// was empty, just fill it
part.data = buff.toByteArray();
}
/*
* Clear this streams buffer, in case flush() is called a second time
* Fix bug 1921637 - provided by Rainer Schwarze
*/
buff.reset();
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
buff.write(b, off, len);
}
@Override
public void write(byte[] b) throws IOException {
buff.write(b);
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Build an output stream for MemoryPackagePart.
*
* @author Julien Chable
* @version 1.0
*/
public final class MemoryPackagePartOutputStream extends OutputStream {
private MemoryPackagePart part;
private ByteArrayOutputStream buff;
public MemoryPackagePartOutputStream(MemoryPackagePart part) {
this.part = part;
buff = new ByteArrayOutputStream();
}
@Override
public void write(int b) throws IOException {
buff.write(b);
}
/**
* Close this stream and flush the content.
* @see #flush()
*/
@Override
public void close() throws IOException {
this.flush();
}
/**
* Flush this output stream. This method is called by the close() method.
* Warning : don't call this method for output consistency.
* @see #close()
*/
@Override
public void flush() throws IOException {
buff.flush();
if (part.data != null) {
byte[] newArray = new byte[part.data.length + buff.size()];
// copy the previous contents of part.data in newArray
System.arraycopy(part.data, 0, newArray, 0, part.data.length);
// append the newly added data
byte[] buffArr = buff.toByteArray();
System.arraycopy(buffArr, 0, newArray, part.data.length,
buffArr.length);
// save the result as new data
part.data = newArray;
} else {
// was empty, just fill it
part.data = buff.toByteArray();
}
/*
* Clear this streams buffer, in case flush() is called a second time
* Fix bug 1921637 - provided by Rainer Schwarze
*/
buff.reset();
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
buff.write(b, off, len);
}
@Override
public void write(byte[] b) throws IOException {
buff.write(b);
}
}

+ 49
- 49
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java View File

@@ -1,49 +1,49 @@
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
/**
* Object implemented this interface are considered as part marshaller. A part
* marshaller is responsible to marshall a part in order to be save in a
* package.
*
* @author Julien Chable
* @version 0.1
*/
public interface PartMarshaller {
/**
* Save the content of the package in the stream
*
* @param part
* Part to marshall.
* @param out
* The output stream into which the part will be marshall.
* @return <b>false</b> if any marshall error occurs, else <b>true</b>
* @throws OpenXML4JException
* Throws only if any other exceptions are thrown by inner
* methods.
*/
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException;
}
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
/**
* Object implemented this interface are considered as part marshaller. A part
* marshaller is responsible to marshall a part in order to be save in a
* package.
*
* @author Julien Chable
* @version 0.1
*/
public interface PartMarshaller {
/**
* Save the content of the package in the stream
*
* @param part
* Part to marshall.
* @param out
* The output stream into which the part will be marshall.
* @return <b>false</b> if any marshall error occurs, else <b>true</b>
* @throws OpenXML4JException
* Throws only if any other exceptions are thrown by inner
* methods.
*/
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException;
}

+ 50
- 50
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java View File

@@ -1,50 +1,50 @@
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext;
/**
* Object implemented this interface are considered as part unmarshaller. A part
* unmarshaller is responsible to unmarshall a part in order to load it from a
* package.
*
* @author Julien Chable
* @version 0.1
*/
public interface PartUnmarshaller {
/**
* Save the content of the package in the stream
*
* @param in
* The input stream from which the part will be unmarshall.
* @return The part freshly unmarshall from the input stream.
* @throws OpenXML4JException
* Throws only if any other exceptions are thrown by inner
* methods.
*/
public PackagePart unmarshall(UnmarshallContext context, InputStream in)
throws InvalidFormatException, IOException;
}
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext;
/**
* Object implemented this interface are considered as part unmarshaller. A part
* unmarshaller is responsible to unmarshall a part in order to load it from a
* package.
*
* @author Julien Chable
* @version 0.1
*/
public interface PartUnmarshaller {
/**
* Save the content of the package in the stream
*
* @param in
* The input stream from which the part will be unmarshall.
* @return The part freshly unmarshall from the input stream.
* @throws OpenXML4JException
* Throws only if any other exceptions are thrown by inner
* methods.
*/
public PackagePart unmarshall(UnmarshallContext context, InputStream in)
throws InvalidFormatException, IOException;
}

+ 163
- 163
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java View File

@@ -1,163 +1,163 @@
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.ZipPackage;
public final class ZipHelper {
/**
* Forward slash use to convert part name between OPC and zip item naming
* conventions.
*/
private final static String FORWARD_SLASH = "/";
/**
* Buffer to read data from file. Use big buffer to improve performaces. the
* InputStream class is reading only 8192 bytes per read call (default value
* set by sun)
*/
public static final int READ_WRITE_FILE_BUFFER_SIZE = 8192;
/**
* Prevent this class to be instancied.
*/
private ZipHelper() {
// Do nothing
}
/**
* Retrieve the zip entry of the core properties part.
*
* @throws OpenXML4JException
* Throws if internal error occurs.
*/
public static ZipEntry getCorePropertiesZipEntry(ZipPackage pkg)
throws OpenXML4JException {
PackageRelationship corePropsRel = pkg.getRelationshipsByType(
PackageRelationshipTypes.CORE_PROPERTIES).getRelationship(0);
if (corePropsRel == null)
return null;
return new ZipEntry(corePropsRel.getTargetURI().getPath());
}
/**
* Retrieve the Zip entry of the content types part.
*/
public static ZipEntry getContentTypeZipEntry(ZipPackage pkg) {
Enumeration entries = pkg.getZipArchive().getEntries();
// Enumerate through the Zip entries until we find the one named
// '[Content_Types].xml'.
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
if (entry.getName().equals(
ContentTypeManager.CONTENT_TYPES_PART_NAME))
return entry;
}
return null;
}
/**
* Convert a zip name into an OPC name by adding a leading forward slash to
* the specified item name.
*
* @param zipItemName
* Zip item name to convert.
* @return An OPC compliant name.
*/
public static String getOPCNameFromZipItemName(String zipItemName) {
if (zipItemName == null)
throw new IllegalArgumentException("zipItemName");
if (zipItemName.startsWith(FORWARD_SLASH))
return zipItemName;
else
return FORWARD_SLASH + zipItemName;
}
/**
* Convert an OPC item name into a zip item name by removing any leading
* forward slash if it exist.
*
* @param opcItemName
* The OPC item name to convert.
* @return A zip item name without any leading slashes.
*/
public static String getZipItemNameFromOPCName(String opcItemName) {
if (opcItemName == null)
throw new IllegalArgumentException("opcItemName");
String retVal = new String(opcItemName);
while (retVal.startsWith(FORWARD_SLASH))
retVal = retVal.substring(1);
return retVal;
}
/**
* Convert an OPC item name into a zip URI by removing any leading forward
* slash if it exist.
*
* @param opcItemName
* The OPC item name to convert.
* @return A zip URI without any leading slashes.
*/
public static URI getZipURIFromOPCName(String opcItemName) {
if (opcItemName == null)
throw new IllegalArgumentException("opcItemName");
String retVal = new String(opcItemName);
while (retVal.startsWith(FORWARD_SLASH))
retVal = retVal.substring(1);
try {
return new URI(retVal);
} catch (URISyntaxException e) {
return null;
}
}
/**
* Retrieve and open a zip file with the specified path.
*
* @param path
* The file path.
* @return The zip archive freshly open.
*/
public static ZipFile openZipFile(String path) {
File f = new File(path);
try {
if (!f.exists()) {
return null;
}
return new ZipFile(f);
} catch (IOException ioe) {
return null;
}
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.ZipPackage;
public final class ZipHelper {
/**
* Forward slash use to convert part name between OPC and zip item naming
* conventions.
*/
private final static String FORWARD_SLASH = "/";
/**
* Buffer to read data from file. Use big buffer to improve performaces. the
* InputStream class is reading only 8192 bytes per read call (default value
* set by sun)
*/
public static final int READ_WRITE_FILE_BUFFER_SIZE = 8192;
/**
* Prevent this class to be instancied.
*/
private ZipHelper() {
// Do nothing
}
/**
* Retrieve the zip entry of the core properties part.
*
* @throws OpenXML4JException
* Throws if internal error occurs.
*/
public static ZipEntry getCorePropertiesZipEntry(ZipPackage pkg)
throws OpenXML4JException {
PackageRelationship corePropsRel = pkg.getRelationshipsByType(
PackageRelationshipTypes.CORE_PROPERTIES).getRelationship(0);
if (corePropsRel == null)
return null;
return new ZipEntry(corePropsRel.getTargetURI().getPath());
}
/**
* Retrieve the Zip entry of the content types part.
*/
public static ZipEntry getContentTypeZipEntry(ZipPackage pkg) {
Enumeration entries = pkg.getZipArchive().getEntries();
// Enumerate through the Zip entries until we find the one named
// '[Content_Types].xml'.
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
if (entry.getName().equals(
ContentTypeManager.CONTENT_TYPES_PART_NAME))
return entry;
}
return null;
}
/**
* Convert a zip name into an OPC name by adding a leading forward slash to
* the specified item name.
*
* @param zipItemName
* Zip item name to convert.
* @return An OPC compliant name.
*/
public static String getOPCNameFromZipItemName(String zipItemName) {
if (zipItemName == null)
throw new IllegalArgumentException("zipItemName");
if (zipItemName.startsWith(FORWARD_SLASH))
return zipItemName;
else
return FORWARD_SLASH + zipItemName;
}
/**
* Convert an OPC item name into a zip item name by removing any leading
* forward slash if it exist.
*
* @param opcItemName
* The OPC item name to convert.
* @return A zip item name without any leading slashes.
*/
public static String getZipItemNameFromOPCName(String opcItemName) {
if (opcItemName == null)
throw new IllegalArgumentException("opcItemName");
String retVal = new String(opcItemName);
while (retVal.startsWith(FORWARD_SLASH))
retVal = retVal.substring(1);
return retVal;
}
/**
* Convert an OPC item name into a zip URI by removing any leading forward
* slash if it exist.
*
* @param opcItemName
* The OPC item name to convert.
* @return A zip URI without any leading slashes.
*/
public static URI getZipURIFromOPCName(String opcItemName) {
if (opcItemName == null)
throw new IllegalArgumentException("opcItemName");
String retVal = new String(opcItemName);
while (retVal.startsWith(FORWARD_SLASH))
retVal = retVal.substring(1);
try {
return new URI(retVal);
} catch (URISyntaxException e) {
return null;
}
}
/**
* Retrieve and open a zip file with the specified path.
*
* @param path
* The file path.
* @return The zip archive freshly open.
*/
public static ZipFile openZipFile(String path) {
File f = new File(path);
try {
if (!f.exists()) {
return null;
}
return new ZipFile(f);
} catch (IOException ioe) {
return null;
}
}
}

+ 45
- 45
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java View File

@@ -1,45 +1,45 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
/**
* Default marshaller that specified that the part is responsible to marshall its content.
*
* @author Julien Chable
* @version 1.0
* @see PartMarshaller
*/
public class DefaultMarshaller implements PartMarshaller {
/**
* Save part in the output stream by using the save() method of the part.
*
* @throws OpenXML4JException
* If any error occur.
*/
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
return part.save(out);
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
/**
* Default marshaller that specified that the part is responsible to marshall its content.
*
* @author Julien Chable
* @version 1.0
* @see PartMarshaller
*/
public final class DefaultMarshaller implements PartMarshaller {
/**
* Save part in the output stream by using the save() method of the part.
*
* @throws OpenXML4JException
* If any error occur.
*/
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
return part.save(out);
}
}

+ 433
- 434
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java View File

@@ -1,434 +1,433 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;
import java.io.OutputStream;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
/**
* Package properties marshaller.
*
* @author CDubet, Julien Chable
* @version 1.0
*/
public class PackagePropertiesMarshaller implements PartMarshaller {
private final static Namespace namespaceDC = new Namespace("dc",
PackagePropertiesPart.NAMESPACE_DC_URI);
private final static Namespace namespaceCoreProperties = new Namespace("",
PackagePropertiesPart.NAMESPACE_CP_URI);
private final static Namespace namespaceDcTerms = new Namespace("dcterms",
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
private final static Namespace namespaceXSI = new Namespace("xsi",
PackagePropertiesPart.NAMESPACE_XSI_URI);
protected static final String KEYWORD_CATEGORY = "category";
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
protected static final String KEYWORD_CREATED = "created";
protected static final String KEYWORD_CREATOR = "creator";
protected static final String KEYWORD_DESCRIPTION = "description";
protected static final String KEYWORD_IDENTIFIER = "identifier";
protected static final String KEYWORD_KEYWORDS = "keywords";
protected static final String KEYWORD_LANGUAGE = "language";
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
protected static final String KEYWORD_MODIFIED = "modified";
protected static final String KEYWORD_REVISION = "revision";
protected static final String KEYWORD_SUBJECT = "subject";
protected static final String KEYWORD_TITLE = "title";
protected static final String KEYWORD_VERSION = "version";
PackagePropertiesPart propsPart;
// The document
Document xmlDoc = null;
/**
* Marshall package core properties to an XML document. Always return
* <code>true</code>.
*/
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
if (!(part instanceof PackagePropertiesPart))
throw new IllegalArgumentException(
"'part' must be a PackagePropertiesPart instance.");
propsPart = (PackagePropertiesPart) part;
// Configure the document
xmlDoc = DocumentHelper.createDocument();
Element rootElem = xmlDoc.addElement(new QName("coreProperties",
namespaceCoreProperties));
rootElem.addNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
rootElem.addNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
rootElem.addNamespace("dcterms",
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
rootElem.addNamespace("xsi", PackagePropertiesPart.NAMESPACE_XSI_URI);
addCategory();
addContentStatus();
addContentType();
addCreated();
addCreator();
addDescription();
addIdentifier();
addKeywords();
addLanguage();
addLastModifiedBy();
addLastPrinted();
addModified();
addRevision();
addSubject();
addTitle();
addVersion();
return true;
}
/**
* Add category property element if needed.
*/
private void addCategory() {
if (!propsPart.getCategoryProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CATEGORY, namespaceCoreProperties));
if (elem == null) {
// Missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CATEGORY, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getCategoryProperty().getValue());
}
/**
* Add content status property element if needed.
*/
private void addContentStatus() {
if (!propsPart.getContentStatusProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties));
if (elem == null) {
// Missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getContentStatusProperty().getValue());
}
/**
* Add content type property element if needed.
*/
private void addContentType() {
if (!propsPart.getContentTypeProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties));
if (elem == null) {
// Missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getContentTypeProperty().getValue());
}
/**
* Add created property element if needed.
*/
private void addCreated() {
if (!propsPart.getCreatedProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATED, namespaceDcTerms));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CREATED, namespaceDcTerms));
} else {
elem.clearContent();// clear the old value
}
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF");
elem.addText(propsPart.getCreatedPropertyString());
}
/**
* Add creator property element if needed.
*/
private void addCreator() {
if (!propsPart.getCreatorProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATOR, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CREATOR, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getCreatorProperty().getValue());
}
/**
* Add description property element if needed.
*/
private void addDescription() {
if (!propsPart.getDescriptionProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_DESCRIPTION, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_DESCRIPTION, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getDescriptionProperty().getValue());
}
/**
* Add identifier property element if needed.
*/
private void addIdentifier() {
if (!propsPart.getIdentifierProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_IDENTIFIER, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_IDENTIFIER, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getIdentifierProperty().getValue());
}
/**
* Add keywords property element if needed.
*/
private void addKeywords() {
if (!propsPart.getKeywordsProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getKeywordsProperty().getValue());
}
/**
* Add language property element if needed.
*/
private void addLanguage() {
if (!propsPart.getLanguageProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_LANGUAGE, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_LANGUAGE, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getLanguageProperty().getValue());
}
/**
* Add 'last modified by' property if needed.
*/
private void addLastModifiedBy() {
if (!propsPart.getLastModifiedByProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement()
.addElement(
new QName(KEYWORD_LAST_MODIFIED_BY,
namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getLastModifiedByProperty().getValue());
}
/**
* Add 'last printed' property if needed.
*
*/
private void addLastPrinted() {
if (!propsPart.getLastPrintedProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getLastPrintedPropertyString());
}
/**
* Add modified property element if needed.
*/
private void addModified() {
if (!propsPart.getModifiedProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
} else {
elem.clearContent();// clear the old value
}
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF");
elem.addText(propsPart.getModifiedPropertyString());
}
/**
* Add revision property if needed.
*/
private void addRevision() {
if (!propsPart.getRevisionProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_REVISION, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_REVISION, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getRevisionProperty().getValue());
}
/**
* Add subject property if needed.
*/
private void addSubject() {
if (!propsPart.getSubjectProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_SUBJECT, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_SUBJECT, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getSubjectProperty().getValue());
}
/**
* Add title property if needed.
*/
private void addTitle() {
if (!propsPart.getTitleProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_TITLE, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_TITLE, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getTitleProperty().getValue());
}
private void addVersion() {
if (!propsPart.getVersionProperty().hasValue())
return;
Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_VERSION, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_VERSION, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getVersionProperty().getValue());
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;

import java.io.OutputStream;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;

/**
* Package properties marshaller.
*
* @author CDubet, Julien Chable
*/
public class PackagePropertiesMarshaller implements PartMarshaller {

private final static Namespace namespaceDC = new Namespace("dc",
PackagePropertiesPart.NAMESPACE_DC_URI);

private final static Namespace namespaceCoreProperties = new Namespace("",
PackagePropertiesPart.NAMESPACE_CP_URI);

private final static Namespace namespaceDcTerms = new Namespace("dcterms",
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);

private final static Namespace namespaceXSI = new Namespace("xsi",
PackagePropertiesPart.NAMESPACE_XSI_URI);

protected static final String KEYWORD_CATEGORY = "category";

protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";

protected static final String KEYWORD_CONTENT_TYPE = "contentType";

protected static final String KEYWORD_CREATED = "created";

protected static final String KEYWORD_CREATOR = "creator";

protected static final String KEYWORD_DESCRIPTION = "description";

protected static final String KEYWORD_IDENTIFIER = "identifier";

protected static final String KEYWORD_KEYWORDS = "keywords";

protected static final String KEYWORD_LANGUAGE = "language";

protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";

protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";

protected static final String KEYWORD_MODIFIED = "modified";

protected static final String KEYWORD_REVISION = "revision";

protected static final String KEYWORD_SUBJECT = "subject";

protected static final String KEYWORD_TITLE = "title";

protected static final String KEYWORD_VERSION = "version";

PackagePropertiesPart propsPart;

// The document
Document xmlDoc = null;

/**
* Marshall package core properties to an XML document. Always return
* <code>true</code>.
*/
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
if (!(part instanceof PackagePropertiesPart))
throw new IllegalArgumentException(
"'part' must be a PackagePropertiesPart instance.");
propsPart = (PackagePropertiesPart) part;

// Configure the document
xmlDoc = DocumentHelper.createDocument();
Element rootElem = xmlDoc.addElement(new QName("coreProperties",
namespaceCoreProperties));
rootElem.addNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
rootElem.addNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
rootElem.addNamespace("dcterms",
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
rootElem.addNamespace("xsi", PackagePropertiesPart.NAMESPACE_XSI_URI);

addCategory();
addContentStatus();
addContentType();
addCreated();
addCreator();
addDescription();
addIdentifier();
addKeywords();
addLanguage();
addLastModifiedBy();
addLastPrinted();
addModified();
addRevision();
addSubject();
addTitle();
addVersion();
return true;
}

/**
* Add category property element if needed.
*/
private void addCategory() {
if (!propsPart.getCategoryProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CATEGORY, namespaceCoreProperties));
if (elem == null) {
// Missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CATEGORY, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getCategoryProperty().getValue());
}

/**
* Add content status property element if needed.
*/
private void addContentStatus() {
if (!propsPart.getContentStatusProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties));
if (elem == null) {
// Missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getContentStatusProperty().getValue());
}

/**
* Add content type property element if needed.
*/
private void addContentType() {
if (!propsPart.getContentTypeProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties));
if (elem == null) {
// Missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getContentTypeProperty().getValue());
}

/**
* Add created property element if needed.
*/
private void addCreated() {
if (!propsPart.getCreatedProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATED, namespaceDcTerms));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CREATED, namespaceDcTerms));
} else {
elem.clearContent();// clear the old value
}
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF");
elem.addText(propsPart.getCreatedPropertyString());
}

/**
* Add creator property element if needed.
*/
private void addCreator() {
if (!propsPart.getCreatorProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATOR, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_CREATOR, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getCreatorProperty().getValue());
}

/**
* Add description property element if needed.
*/
private void addDescription() {
if (!propsPart.getDescriptionProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_DESCRIPTION, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_DESCRIPTION, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getDescriptionProperty().getValue());
}

/**
* Add identifier property element if needed.
*/
private void addIdentifier() {
if (!propsPart.getIdentifierProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_IDENTIFIER, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_IDENTIFIER, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getIdentifierProperty().getValue());
}

/**
* Add keywords property element if needed.
*/
private void addKeywords() {
if (!propsPart.getKeywordsProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getKeywordsProperty().getValue());
}

/**
* Add language property element if needed.
*/
private void addLanguage() {
if (!propsPart.getLanguageProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_LANGUAGE, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_LANGUAGE, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getLanguageProperty().getValue());
}

/**
* Add 'last modified by' property if needed.
*/
private void addLastModifiedBy() {
if (!propsPart.getLastModifiedByProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement()
.addElement(
new QName(KEYWORD_LAST_MODIFIED_BY,
namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getLastModifiedByProperty().getValue());
}

/**
* Add 'last printed' property if needed.
*
*/
private void addLastPrinted() {
if (!propsPart.getLastPrintedProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getLastPrintedPropertyString());
}

/**
* Add modified property element if needed.
*/
private void addModified() {
if (!propsPart.getModifiedProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
} else {
elem.clearContent();// clear the old value
}
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF");
elem.addText(propsPart.getModifiedPropertyString());
}

/**
* Add revision property if needed.
*/
private void addRevision() {
if (!propsPart.getRevisionProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_REVISION, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_REVISION, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getRevisionProperty().getValue());
}

/**
* Add subject property if needed.
*/
private void addSubject() {
if (!propsPart.getSubjectProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_SUBJECT, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_SUBJECT, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getSubjectProperty().getValue());
}

/**
* Add title property if needed.
*/
private void addTitle() {
if (!propsPart.getTitleProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_TITLE, namespaceDC));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_TITLE, namespaceDC));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getTitleProperty().getValue());
}

private void addVersion() {
if (!propsPart.getVersionProperty().hasValue())
return;

Element elem = xmlDoc.getRootElement().element(
new QName(KEYWORD_VERSION, namespaceCoreProperties));
if (elem == null) {
// missing, we add it
elem = xmlDoc.getRootElement().addElement(
new QName(KEYWORD_VERSION, namespaceCoreProperties));
} else {
elem.clearContent();// clear the old value
}
elem.addText(propsPart.getVersionProperty().getValue());
}
}

+ 63
- 64
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java View File

@@ -1,64 +1,63 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.StreamHelper;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
/**
* Package core properties marshaller specialized for zipped package.
*
* @author Julien Chable
* @version 1.0
*/
public class ZipPackagePropertiesMarshaller extends PackagePropertiesMarshaller {
@Override
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
if (!(out instanceof ZipOutputStream)) {
throw new IllegalArgumentException("ZipOutputStream expected!");
}
ZipOutputStream zos = (ZipOutputStream) out;
// Saving the part in the zip file
ZipEntry ctEntry = new ZipEntry(ZipHelper
.getZipItemNameFromOPCName(part.getPartName().getURI()
.toString()));
try {
// Save in ZIP
zos.putNextEntry(ctEntry); // Add entry in ZIP
super.marshall(part, out); // Marshall the properties inside a XML
// Document
if (!StreamHelper.saveXmlInStream(xmlDoc, out)) {
return false;
}
zos.closeEntry();
} catch (IOException e) {
throw new OpenXML4JException(e.getLocalizedMessage());
}
return true;
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;

import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.StreamHelper;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;

/**
* Package core properties marshaller specialized for zipped package.
*
* @author Julien Chable
*/
public final class ZipPackagePropertiesMarshaller extends PackagePropertiesMarshaller {

@Override
public boolean marshall(PackagePart part, OutputStream out)
throws OpenXML4JException {
if (!(out instanceof ZipOutputStream)) {
throw new IllegalArgumentException("ZipOutputStream expected!");
}
ZipOutputStream zos = (ZipOutputStream) out;

// Saving the part in the zip file
ZipEntry ctEntry = new ZipEntry(ZipHelper
.getZipItemNameFromOPCName(part.getPartName().getURI()
.toString()));
try {
// Save in ZIP
zos.putNextEntry(ctEntry); // Add entry in ZIP
super.marshall(part, out); // Marshall the properties inside a XML
// Document
if (!StreamHelper.saveXmlInStream(xmlDoc, out)) {
return false;
}
zos.closeEntry();
} catch (IOException e) {
throw new OpenXML4JException(e.getLocalizedMessage());
}
return true;
}
}

+ 191
- 193
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java View File

@@ -1,193 +1,191 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.StreamHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
/**
* Zip part marshaller. This marshaller is use to save any part in a zip stream.
*
* @author Julien Chable
* @version 0.1
*/
public class ZipPartMarshaller implements PartMarshaller {
private static POILogger logger = POILogFactory.getLogger(ZipPartMarshaller.class);
/**
* Save the specified part.
*
* @throws OpenXML4JException
* Throws if an internal exception is thrown.
*/
public boolean marshall(PackagePart part, OutputStream os)
throws OpenXML4JException {
if (!(os instanceof ZipOutputStream)) {
logger.log(POILogger.ERROR,"Unexpected class " + os.getClass().getName());
throw new OpenXML4JException("ZipOutputStream expected !");
// Normally should happen only in developpement phase, so just throw
// exception
}
ZipOutputStream zos = (ZipOutputStream) os;
ZipEntry partEntry = new ZipEntry(ZipHelper
.getZipItemNameFromOPCName(part.getPartName().getURI()
.getPath()));
try {
// Create next zip entry
zos.putNextEntry(partEntry);
// Saving data in the ZIP file
InputStream ins = part.getInputStream();
byte[] buff = new byte[ZipHelper.READ_WRITE_FILE_BUFFER_SIZE];
while (ins.available() > 0) {
int resultRead = ins.read(buff);
if (resultRead == -1) {
// End of file reached
break;
} else {
zos.write(buff, 0, resultRead);
}
}
zos.closeEntry();
} catch (IOException ioe) {
logger.log(POILogger.ERROR,"Cannot write: " + part.getPartName() + ": in ZIP",
ioe);
return false;
}
// Saving relationship part
if (part.hasRelationships()) {
PackagePartName relationshipPartName = PackagingURIHelper
.getRelationshipPartName(part.getPartName());
marshallRelationshipPart(part.getRelationships(),
relationshipPartName, zos);
}
return true;
}
/**
* Save relationships into the part.
*
* @param rels
* The relationships collection to marshall.
* @param relPartName
* Part name of the relationship part to marshall.
* @param zos
* Zip output stream in which to save the XML content of the
* relationships serialization.
*/
public static boolean marshallRelationshipPart(
PackageRelationshipCollection rels, PackagePartName relPartName,
ZipOutputStream zos) {
// Building xml
Document xmlOutDoc = DocumentHelper.createDocument();
// make something like <Relationships
// xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
Namespace dfNs = Namespace.get("", PackageNamespaces.RELATIONSHIPS);
Element root = xmlOutDoc.addElement(new QName(
PackageRelationship.RELATIONSHIPS_TAG_NAME, dfNs));
// <Relationship
// TargetMode="External"
// Id="rIdx"
// Target="http://www.custom.com/images/pic1.jpg"
// Type="http://www.custom.com/external-resource"/>
URI sourcePartURI = PackagingURIHelper
.getSourcePartUriFromRelationshipPartUri(relPartName.getURI());
for (PackageRelationship rel : rels) {
// the relationship element
Element relElem = root
.addElement(PackageRelationship.RELATIONSHIP_TAG_NAME);
// the relationship ID
relElem.addAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel
.getId());
// the relationship Type
relElem.addAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel
.getRelationshipType());
// the relationship Target
String targetValue;
URI uri = rel.getTargetURI();
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
// Save the target as-is - we don't need to validate it,
// alter it etc
targetValue = uri.toString();
// add TargetMode attribute (as it is external link external)
relElem.addAttribute(
PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME,
"External");
} else {
targetValue = PackagingURIHelper.relativizeURI(
sourcePartURI, rel.getTargetURI()).getPath();
}
relElem.addAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME,
targetValue);
}
xmlOutDoc.normalize();
// String schemaFilename = Configuration.getPathForXmlSchema()+
// File.separator + "opc-relationships.xsd";
// Save part in zip
ZipEntry ctEntry = new ZipEntry(ZipHelper.getZipURIFromOPCName(
relPartName.getURI().toASCIIString()).getPath());
try {
zos.putNextEntry(ctEntry);
if (!StreamHelper.saveXmlInStream(xmlOutDoc, zos)) {
return false;
}
zos.closeEntry();
} catch (IOException e) {
logger.log(POILogger.ERROR,"Cannot create zip entry " + relPartName, e);
return false;
}
return true; // success
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal.marshallers;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.StreamHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;

/**
* Zip part marshaller. This marshaller is use to save any part in a zip stream.
*
* @author Julien Chable
*/
public final class ZipPartMarshaller implements PartMarshaller {
private static POILogger logger = POILogFactory.getLogger(ZipPartMarshaller.class);

/**
* Save the specified part.
*
* @throws OpenXML4JException
* Throws if an internal exception is thrown.
*/
public boolean marshall(PackagePart part, OutputStream os)
throws OpenXML4JException {
if (!(os instanceof ZipOutputStream)) {
logger.log(POILogger.ERROR,"Unexpected class " + os.getClass().getName());
throw new OpenXML4JException("ZipOutputStream expected !");
// Normally should happen only in developement phase, so just throw
// exception
}

ZipOutputStream zos = (ZipOutputStream) os;
ZipEntry partEntry = new ZipEntry(ZipHelper
.getZipItemNameFromOPCName(part.getPartName().getURI()
.getPath()));
try {
// Create next zip entry
zos.putNextEntry(partEntry);

// Saving data in the ZIP file
InputStream ins = part.getInputStream();
byte[] buff = new byte[ZipHelper.READ_WRITE_FILE_BUFFER_SIZE];
while (ins.available() > 0) {
int resultRead = ins.read(buff);
if (resultRead == -1) {
// End of file reached
break;
}
zos.write(buff, 0, resultRead);
}
zos.closeEntry();
} catch (IOException ioe) {
logger.log(POILogger.ERROR,"Cannot write: " + part.getPartName() + ": in ZIP",
ioe);
return false;
}

// Saving relationship part
if (part.hasRelationships()) {
PackagePartName relationshipPartName = PackagingURIHelper
.getRelationshipPartName(part.getPartName());

marshallRelationshipPart(part.getRelationships(),
relationshipPartName, zos);

}
return true;
}

/**
* Save relationships into the part.
*
* @param rels
* The relationships collection to marshall.
* @param relPartName
* Part name of the relationship part to marshall.
* @param zos
* Zip output stream in which to save the XML content of the
* relationships serialization.
*/
public static boolean marshallRelationshipPart(
PackageRelationshipCollection rels, PackagePartName relPartName,
ZipOutputStream zos) {
// Building xml
Document xmlOutDoc = DocumentHelper.createDocument();
// make something like <Relationships
// xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
Namespace dfNs = Namespace.get("", PackageNamespaces.RELATIONSHIPS);
Element root = xmlOutDoc.addElement(new QName(
PackageRelationship.RELATIONSHIPS_TAG_NAME, dfNs));

// <Relationship
// TargetMode="External"
// Id="rIdx"
// Target="http://www.custom.com/images/pic1.jpg"
// Type="http://www.custom.com/external-resource"/>

URI sourcePartURI = PackagingURIHelper
.getSourcePartUriFromRelationshipPartUri(relPartName.getURI());

for (PackageRelationship rel : rels) {
// the relationship element
Element relElem = root
.addElement(PackageRelationship.RELATIONSHIP_TAG_NAME);

// the relationship ID
relElem.addAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel
.getId());

// the relationship Type
relElem.addAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel
.getRelationshipType());

// the relationship Target
String targetValue;
URI uri = rel.getTargetURI();
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
// Save the target as-is - we don't need to validate it,
// alter it etc
targetValue = uri.toString();

// add TargetMode attribute (as it is external link external)
relElem.addAttribute(
PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME,
"External");
} else {
targetValue = PackagingURIHelper.relativizeURI(
sourcePartURI, rel.getTargetURI()).getPath();
}
relElem.addAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME,
targetValue);
}

xmlOutDoc.normalize();

// String schemaFilename = Configuration.getPathForXmlSchema()+
// File.separator + "opc-relationships.xsd";

// Save part in zip
ZipEntry ctEntry = new ZipEntry(ZipHelper.getZipURIFromOPCName(
relPartName.getURI().toASCIIString()).getPath());
try {
zos.putNextEntry(ctEntry);
if (!StreamHelper.saveXmlInStream(xmlOutDoc, zos)) {
return false;
}
zos.closeEntry();
} catch (IOException e) {
logger.log(POILogger.ERROR,"Cannot create zip entry " + relPartName, e);
return false;
}
return true; // success
}
}

+ 78
- 78
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalCertificatePart.java View File

@@ -1,78 +1,78 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.signature;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.ContentType;
/**
* Digital certificate part.
*
* @author Julien Chable
* @version 0.1
*/
public final class DigitalCertificatePart extends PackagePart {
public DigitalCertificatePart() throws InvalidFormatException{
super(null, null, new ContentType(""));
// Review constructor
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
@Override
protected InputStream getInputStreamImpl() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
protected OutputStream getOutputStreamImpl() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean load(InputStream ios) throws InvalidFormatException {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean save(OutputStream zos) throws OpenXML4JException {
// TODO Auto-generated method stub
return false;
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal.signature;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.ContentType;
/**
* Digital certificate part.
*
* @author Julien Chable
* @version 0.1
*/
public final class DigitalCertificatePart extends PackagePart {
public DigitalCertificatePart() throws InvalidFormatException{
super(null, null, new ContentType(""));
// Review constructor
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
@Override
protected InputStream getInputStreamImpl() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
protected OutputStream getOutputStreamImpl() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean load(InputStream ios) throws InvalidFormatException {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean save(OutputStream zos) throws OpenXML4JException {
// TODO Auto-generated method stub
return false;
}
}

+ 28
- 28
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalSignatureOriginPart.java View File

@@ -1,28 +1,28 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.signature;
/**
* Represents a digital signature origin part.
*
* @author Julien Chable
* @version 0.1
*/
public class DigitalSignatureOriginPart {
}
/* ====================================================================
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.poi.openxml4j.opc.internal.signature;
/**
* Represents a digital signature origin part.
*
* @author Julien Chable
* @version 0.1
*/
public final class DigitalSignatureOriginPart {
}

+ 393
- 391
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java View File

@@ -1,391 +1,393 @@
/* ====================================================================
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.poi.openxml4j.opc.internal.unmarshallers;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageProperties;
import org.apache.poi.openxml4j.opc.ZipPackage;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
/**
* Package properties unmarshaller.
*
* @author Julien Chable
* @version 1.0
*/
public class PackagePropertiesUnmarshaller implements PartUnmarshaller {
private final static Namespace namespaceDC = new Namespace("dc",
PackageProperties.NAMESPACE_DC);
private final static Namespace namespaceCP = new Namespace("cp",
PackageNamespaces.CORE_PROPERTIES);
private final static Namespace namespaceDcTerms = new Namespace("dcterms",
PackageProperties.NAMESPACE_DCTERMS);
private final static Namespace namespaceXML = new Namespace("xml",
"http://www.w3.org/XML/1998/namespace");
private final static Namespace namespaceXSI = new Namespace("xsi",
"http://www.w3.org/2001/XMLSchema-instance");
protected static final String KEYWORD_CATEGORY = "category";
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
protected static final String KEYWORD_CREATED = "created";
protected static final String KEYWORD_CREATOR = "creator";
protected static final String KEYWORD_DESCRIPTION = "description";
protected static final String KEYWORD_IDENTIFIER = "identifier";
protected static final String KEYWORD_KEYWORDS = "keywords";
protected static final String KEYWORD_LANGUAGE = "language";
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
protected static final String KEYWORD_MODIFIED = "modified";
protected static final String KEYWORD_REVISION = "revision";
protected static final String KEYWORD_SUBJECT = "subject";
protected static final String KEYWORD_TITLE = "title";
protected static final String KEYWORD_VERSION = "version";
// TODO Load element with XMLBeans or dynamic table
// TODO Check every element/namespace for compliance
public PackagePart unmarshall(UnmarshallContext context, InputStream in)
throws InvalidFormatException, IOException {
PackagePropertiesPart coreProps = new PackagePropertiesPart(context
.getPackage(), context.getPartName());
// If the input stream is null then we try to get it from the
// package.
if (in == null) {
if (context.getZipEntry() != null) {
in = ((ZipPackage) context.getPackage()).getZipArchive()
.getInputStream(context.getZipEntry());
} else if (context.getPackage() != null) {
// Try to retrieve the part inputstream from the URI
ZipEntry zipEntry;
try {
zipEntry = ZipHelper
.getCorePropertiesZipEntry((ZipPackage) context
.getPackage());
} catch (OpenXML4JException e) {
throw new IOException(
"Error while trying to get the part input stream.");
}
in = ((ZipPackage) context.getPackage()).getZipArchive()
.getInputStream(zipEntry);
} else
throw new IOException(
"Error while trying to get the part input stream.");
}
SAXReader xmlReader = new SAXReader();
Document xmlDoc;
try {
xmlDoc = xmlReader.read(in);
/* Check OPC compliance */
// Rule M4.2, M4.3, M4.4 and M4.5/
checkElementForOPCCompliance(xmlDoc.getRootElement());
/* End OPC compliance */
} catch (DocumentException e) {
throw new IOException(e.getMessage());
}
coreProps.setCategoryProperty(loadCategory(xmlDoc));
coreProps.setContentStatusProperty(loadContentStatus(xmlDoc));
coreProps.setContentTypeProperty(loadContentType(xmlDoc));
coreProps.setCreatedProperty(loadCreated(xmlDoc));
coreProps.setCreatorProperty(loadCreator(xmlDoc));
coreProps.setDescriptionProperty(loadDescription(xmlDoc));
coreProps.setIdentifierProperty(loadIdentifier(xmlDoc));
coreProps.setKeywordsProperty(loadKeywords(xmlDoc));
coreProps.setLanguageProperty(loadLanguage(xmlDoc));
coreProps.setLastModifiedByProperty(loadLastModifiedBy(xmlDoc));
coreProps.setLastPrintedProperty(loadLastPrinted(xmlDoc));
coreProps.setModifiedProperty(loadModified(xmlDoc));
coreProps.setRevisionProperty(loadRevision(xmlDoc));
coreProps.setSubjectProperty(loadSubject(xmlDoc));
coreProps.setTitleProperty(loadTitle(xmlDoc));
coreProps.setVersionProperty(loadVersion(xmlDoc));
return coreProps;
}
private String loadCategory(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CATEGORY, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadContentStatus(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_STATUS, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadContentType(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_TYPE, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadCreated(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATED, namespaceDcTerms));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadCreator(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATOR, namespaceDC));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadDescription(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_DESCRIPTION, namespaceDC));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadIdentifier(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_IDENTIFIER, namespaceDC));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadKeywords(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_KEYWORDS, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadLanguage(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_LANGUAGE, namespaceDC));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadLastModifiedBy(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadLastPrinted(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_PRINTED, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadModified(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadRevision(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_REVISION, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadSubject(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_SUBJECT, namespaceDC));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadTitle(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_TITLE, namespaceDC));
if (el != null)
return el.getStringValue();
else
return null;
}
private String loadVersion(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_VERSION, namespaceCP));
if (el != null)
return el.getStringValue();
else
return null;
}
/* OPC Compliance methods */
/**
* Check the element for the following OPC compliance rules:
* <p>
* Rule M4.2: A format consumer shall consider the use of the Markup
* Compatibility namespace to be an error.
* </p><p>
* Rule M4.3: Producers shall not create a document element that contains
* refinements to the Dublin Core elements, except for the two specified in
* the schema: <dcterms:created> and <dcterms:modified> Consumers shall
* consider a document element that violates this constraint to be an error.
* </p><p>
* Rule M4.4: Producers shall not create a document element that contains
* the xml:lang attribute. Consumers shall consider a document element that
* violates this constraint to be an error.
* </p><p>
* Rule M4.5: Producers shall not create a document element that contains
* the xsi:type attribute, except for a <dcterms:created> or
* <dcterms:modified> element where the xsi:type attribute shall be present
* and shall hold the value dcterms:W3CDTF, where dcterms is the namespace
* prefix of the Dublin Core namespace. Consumers shall consider a document
* element that violates this constraint to be an error.
* </p>
*/
public void checkElementForOPCCompliance(Element el)
throws InvalidFormatException {
// Check the current element
List declaredNamespaces = el.declaredNamespaces();
Iterator itNS = declaredNamespaces.iterator();
while (itNS.hasNext()) {
Namespace ns = (Namespace) itNS.next();
// Rule M4.2
if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY))
throw new InvalidFormatException(
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.");
}
// Rule M4.3
if (el.getNamespace().getURI().equals(
PackageProperties.NAMESPACE_DCTERMS)
&& !(el.getName().equals(KEYWORD_CREATED) || el.getName()
.equals(KEYWORD_MODIFIED)))
throw new InvalidFormatException(
"OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error.");
// Rule M4.4
if (el.attribute(new QName("lang", namespaceXML)) != null)
throw new InvalidFormatException(
"OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error.");
// Rule M4.5
if (el.getNamespace().getURI().equals(
PackageProperties.NAMESPACE_DCTERMS)) {
// DCTerms namespace only use with 'created' and 'modified' elements
String elName = el.getName();
if (!(elName.equals(KEYWORD_CREATED) || elName
.equals(KEYWORD_MODIFIED)))
throw new InvalidFormatException("Namespace error : " + elName
+ " shouldn't have the following naemspace -> "
+ PackageProperties.NAMESPACE_DCTERMS);
// Check for the 'xsi:type' attribute
Attribute typeAtt = el.attribute(new QName("type", namespaceXSI));
if (typeAtt == null)
throw new InvalidFormatException("The element '" + elName
+ "' must have the '" + namespaceXSI.getPrefix()
+ ":type' attribute present !");
// Check for the attribute value => 'dcterms:W3CDTF'
if (!typeAtt.getValue().equals("dcterms:W3CDTF"))
throw new InvalidFormatException("The element '" + elName
+ "' must have the '" + namespaceXSI.getPrefix()
+ ":type' attribute with the value 'dcterms:W3CDTF' !");
}
// Check its children
Iterator itChildren = el.elementIterator();
while (itChildren.hasNext())
checkElementForOPCCompliance((Element) itChildren.next());
}
}
/* ====================================================================
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.poi.openxml4j.opc.internal.unmarshallers;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackageNamespaces;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageProperties;
import org.apache.poi.openxml4j.opc.ZipPackage;
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;

/**
* Package properties unmarshaller.
*
* @author Julien Chable
* @version 1.0
*/
public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {

private final static Namespace namespaceDC = new Namespace("dc",
PackageProperties.NAMESPACE_DC);

private final static Namespace namespaceCP = new Namespace("cp",
PackageNamespaces.CORE_PROPERTIES);

private final static Namespace namespaceDcTerms = new Namespace("dcterms",
PackageProperties.NAMESPACE_DCTERMS);

private final static Namespace namespaceXML = new Namespace("xml",
"http://www.w3.org/XML/1998/namespace");

private final static Namespace namespaceXSI = new Namespace("xsi",
"http://www.w3.org/2001/XMLSchema-instance");

protected static final String KEYWORD_CATEGORY = "category";

protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";

protected static final String KEYWORD_CONTENT_TYPE = "contentType";

protected static final String KEYWORD_CREATED = "created";

protected static final String KEYWORD_CREATOR = "creator";

protected static final String KEYWORD_DESCRIPTION = "description";

protected static final String KEYWORD_IDENTIFIER = "identifier";

protected static final String KEYWORD_KEYWORDS = "keywords";

protected static final String KEYWORD_LANGUAGE = "language";

protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";

protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";

protected static final String KEYWORD_MODIFIED = "modified";

protected static final String KEYWORD_REVISION = "revision";

protected static final String KEYWORD_SUBJECT = "subject";

protected static final String KEYWORD_TITLE = "title";

protected static final String KEYWORD_VERSION = "version";

// TODO Load element with XMLBeans or dynamic table
// TODO Check every element/namespace for compliance
public PackagePart unmarshall(UnmarshallContext context, InputStream in)
throws InvalidFormatException, IOException {
PackagePropertiesPart coreProps = new PackagePropertiesPart(context
.getPackage(), context.getPartName());

// If the input stream is null then we try to get it from the
// package.
if (in == null) {
if (context.getZipEntry() != null) {
in = ((ZipPackage) context.getPackage()).getZipArchive()
.getInputStream(context.getZipEntry());
} else if (context.getPackage() != null) {
// Try to retrieve the part inputstream from the URI
ZipEntry zipEntry;
try {
zipEntry = ZipHelper
.getCorePropertiesZipEntry((ZipPackage) context
.getPackage());
} catch (OpenXML4JException e) {
throw new IOException(
"Error while trying to get the part input stream.");
}
in = ((ZipPackage) context.getPackage()).getZipArchive()
.getInputStream(zipEntry);
} else
throw new IOException(
"Error while trying to get the part input stream.");
}

SAXReader xmlReader = new SAXReader();
Document xmlDoc;
try {
xmlDoc = xmlReader.read(in);

/* Check OPC compliance */

// Rule M4.2, M4.3, M4.4 and M4.5/
checkElementForOPCCompliance(xmlDoc.getRootElement());

/* End OPC compliance */

} catch (DocumentException e) {
throw new IOException(e.getMessage());
}

coreProps.setCategoryProperty(loadCategory(xmlDoc));
coreProps.setContentStatusProperty(loadContentStatus(xmlDoc));
coreProps.setContentTypeProperty(loadContentType(xmlDoc));
coreProps.setCreatedProperty(loadCreated(xmlDoc));
coreProps.setCreatorProperty(loadCreator(xmlDoc));
coreProps.setDescriptionProperty(loadDescription(xmlDoc));
coreProps.setIdentifierProperty(loadIdentifier(xmlDoc));
coreProps.setKeywordsProperty(loadKeywords(xmlDoc));
coreProps.setLanguageProperty(loadLanguage(xmlDoc));
coreProps.setLastModifiedByProperty(loadLastModifiedBy(xmlDoc));
coreProps.setLastPrintedProperty(loadLastPrinted(xmlDoc));
coreProps.setModifiedProperty(loadModified(xmlDoc));
coreProps.setRevisionProperty(loadRevision(xmlDoc));
coreProps.setSubjectProperty(loadSubject(xmlDoc));
coreProps.setTitleProperty(loadTitle(xmlDoc));
coreProps.setVersionProperty(loadVersion(xmlDoc));

return coreProps;
}

private String loadCategory(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CATEGORY, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadContentStatus(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_STATUS, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadContentType(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CONTENT_TYPE, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadCreated(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATED, namespaceDcTerms));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadCreator(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_CREATOR, namespaceDC));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadDescription(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_DESCRIPTION, namespaceDC));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadIdentifier(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_IDENTIFIER, namespaceDC));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadKeywords(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_KEYWORDS, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadLanguage(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_LANGUAGE, namespaceDC));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadLastModifiedBy(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadLastPrinted(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_LAST_PRINTED, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadModified(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadRevision(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_REVISION, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadSubject(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_SUBJECT, namespaceDC));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadTitle(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_TITLE, namespaceDC));
if (el == null) {
return null;
}
return el.getStringValue();
}

private String loadVersion(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element(
new QName(KEYWORD_VERSION, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
}

/* OPC Compliance methods */

/**
* Check the element for the following OPC compliance rules:
* <p>
* Rule M4.2: A format consumer shall consider the use of the Markup
* Compatibility namespace to be an error.
* </p><p>
* Rule M4.3: Producers shall not create a document element that contains
* refinements to the Dublin Core elements, except for the two specified in
* the schema: <dcterms:created> and <dcterms:modified> Consumers shall
* consider a document element that violates this constraint to be an error.
* </p><p>
* Rule M4.4: Producers shall not create a document element that contains
* the xml:lang attribute. Consumers shall consider a document element that
* violates this constraint to be an error.
* </p><p>
* Rule M4.5: Producers shall not create a document element that contains
* the xsi:type attribute, except for a <dcterms:created> or
* <dcterms:modified> element where the xsi:type attribute shall be present
* and shall hold the value dcterms:W3CDTF, where dcterms is the namespace
* prefix of the Dublin Core namespace. Consumers shall consider a document
* element that violates this constraint to be an error.
* </p>
*/
public void checkElementForOPCCompliance(Element el)
throws InvalidFormatException {
// Check the current element
@SuppressWarnings("unchecked")
List<Namespace> declaredNamespaces = el.declaredNamespaces();
Iterator<Namespace> itNS = declaredNamespaces.iterator();
while (itNS.hasNext()) {
Namespace ns = itNS.next();

// Rule M4.2
if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY))
throw new InvalidFormatException(
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.");
}

// Rule M4.3
if (el.getNamespace().getURI().equals(
PackageProperties.NAMESPACE_DCTERMS)
&& !(el.getName().equals(KEYWORD_CREATED) || el.getName()
.equals(KEYWORD_MODIFIED)))
throw new InvalidFormatException(
"OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error.");

// Rule M4.4
if (el.attribute(new QName("lang", namespaceXML)) != null)
throw new InvalidFormatException(
"OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error.");

// Rule M4.5
if (el.getNamespace().getURI().equals(
PackageProperties.NAMESPACE_DCTERMS)) {
// DCTerms namespace only use with 'created' and 'modified' elements
String elName = el.getName();
if (!(elName.equals(KEYWORD_CREATED) || elName
.equals(KEYWORD_MODIFIED)))
throw new InvalidFormatException("Namespace error : " + elName
+ " shouldn't have the following naemspace -> "
+ PackageProperties.NAMESPACE_DCTERMS);

// Check for the 'xsi:type' attribute
Attribute typeAtt = el.attribute(new QName("type", namespaceXSI));
if (typeAtt == null)
throw new InvalidFormatException("The element '" + elName
+ "' must have the '" + namespaceXSI.getPrefix()
+ ":type' attribute present !");

// Check for the attribute value => 'dcterms:W3CDTF'
if (!typeAtt.getValue().equals("dcterms:W3CDTF"))
throw new InvalidFormatException("The element '" + elName
+ "' must have the '" + namespaceXSI.getPrefix()
+ ":type' attribute with the value 'dcterms:W3CDTF' !");
}

// Check its children
@SuppressWarnings("unchecked")
Iterator<Element> itChildren = el.elementIterator();
while (itChildren.hasNext())
checkElementForOPCCompliance(itChildren.next());
}
}

+ 70
- 70
src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignature.java View File

@@ -1,70 +1,70 @@
/* ====================================================================
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.poi.openxml4j.opc.signature;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.ContentType;
public class PackageDigitalSignature extends PackagePart {
public PackageDigitalSignature() throws InvalidFormatException {
super(null, null, new ContentType(""));
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
@Override
protected InputStream getInputStreamImpl() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
protected OutputStream getOutputStreamImpl() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean load(InputStream ios) throws InvalidFormatException {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean save(OutputStream zos) throws OpenXML4JException {
// TODO Auto-generated method stub
return false;
}
}
/* ====================================================================
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.poi.openxml4j.opc.signature;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.internal.ContentType;
public final class PackageDigitalSignature extends PackagePart {
public PackageDigitalSignature() throws InvalidFormatException {
super(null, null, new ContentType(""));
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
@Override
protected InputStream getInputStreamImpl() throws IOException {
// TODO Auto-generated method stub
return null;
}
@Override
protected OutputStream getOutputStreamImpl() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean load(InputStream ios) throws InvalidFormatException {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean save(OutputStream zos) throws OpenXML4JException {
// TODO Auto-generated method stub
return false;
}
}

+ 22
- 22
src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignatureManager.java View File

@@ -1,22 +1,22 @@
/* ====================================================================
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.poi.openxml4j.opc.signature;
public class PackageDigitalSignatureManager {
}
/* ====================================================================
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.poi.openxml4j.opc.signature;
public final class PackageDigitalSignatureManager {
}

+ 72
- 71
src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java View File

@@ -1,71 +1,72 @@
/* ====================================================================
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.poi.openxml4j.util;
/**
* An immutable object that could be defined as null.
*
* @author Julien Chable
* @version 0.9
*/
public final class Nullable<E> {
private E value;
/**
* Constructor.
*/
public Nullable() {
// Do nothing
}
/**
* Constructor.
*
* @param value
* The value to set to this nullable.
*/
public Nullable(E value) {
this.value = value;
}
/**
* Get the store value if any.
*
* @return the store value
*/
public E getValue() {
return value;
}
/**
* Get the status of this nullable.
*
* @return <b>true</b> if the nullable store a value (empty string is
* considered to be a value) else <b>false</>.
*/
public boolean hasValue() {
return value != null;
}
/**
* Set the stored value to <i>null</i>.
*/
public void nullify() {
value = null;
}
}
/* ====================================================================
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.poi.openxml4j.util;

/**
* An immutable object that could be defined as null.
*
* @author Julien Chable
* @version 0.9
*/
public final class Nullable<E> {

private E value;

/**
* Constructor.
*/
public Nullable() {
// Do nothing
}

/**
* Constructor.
*
* @param value
* The value to set to this nullable.
*/
public Nullable(E value) {
this.value = value;
}

/**
* Get the store value if any.
*
* @return the store value
*/
public E getValue() {
return value;
}

/**
* Get the status of this nullable.
*
* @return <b>true</b> if the nullable store a value (empty string is
* considered to be a value) else <b>false</>.
*/
public boolean hasValue() {
return value != null;
}

/**
* Set the stored value to <i>null</i>.
*/
public void nullify() {
value = null;
}
}

+ 91
- 90
src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java View File

@@ -1,90 +1,91 @@
/* ====================================================================
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.poi.xssf.dev;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
/**
* Utility class which dumps the contents of a *.xlsx file into file system.
*
* @author Yegor Kozlov
*/
public class XSSFDump {
public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
System.out.println("Dumping " + args[i]);
ZipFile zip = new ZipFile(args[i]);
dump(zip);
}
}
public static void dump(ZipFile zip) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
String zipname = zip.getName();
int sep = zipname.lastIndexOf('.');
File root = new File(zipname.substring(0, sep));
root.mkdir();
Enumeration en = zip.entries();
while(en.hasMoreElements()){
ZipEntry entry = (ZipEntry)en.nextElement();
String name = entry.getName();
int idx = name.lastIndexOf('/');
if(idx != -1){
File bs = new File(root, name.substring(0, idx));
bs.mkdirs();
}
File f = new File(root, entry.getName());
FileOutputStream out = new FileOutputStream(f);
if(entry.getName().endsWith(".xml") || entry.getName().endsWith(".vml") || entry.getName().endsWith(".rels")){
try {
XmlObject xml = XmlObject.Factory.parse(zip.getInputStream(entry));
XmlOptions options = new XmlOptions();
options.setSavePrettyPrint();
xml.save(out, options);
} catch (Exception e){
System.err.println("Failed to parse " + entry.getName() + ", dumping raw content");
dump(zip.getInputStream(entry), out);
}
} else {
dump(zip.getInputStream(entry), out);
}
out.close();
}
}
protected static void dump(InputStream is, OutputStream out) throws IOException{
int pos;
byte[] chunk = new byte[2048];
while((pos = is.read(chunk)) > 0) out.write(chunk, 0, pos);
}
}
/* ====================================================================
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.poi.xssf.dev;

import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;

/**
* Utility class which dumps the contents of a *.xlsx file into file system.
*
* @author Yegor Kozlov
*/
public final class XSSFDump {

public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
System.out.println("Dumping " + args[i]);
ZipFile zip = new ZipFile(args[i]);
dump(zip);
}
}

public static void dump(ZipFile zip) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

String zipname = zip.getName();
int sep = zipname.lastIndexOf('.');
File root = new File(zipname.substring(0, sep));
root.mkdir();

Enumeration en = zip.entries();
while(en.hasMoreElements()){
ZipEntry entry = (ZipEntry)en.nextElement();
String name = entry.getName();
int idx = name.lastIndexOf('/');
if(idx != -1){
File bs = new File(root, name.substring(0, idx));
bs.mkdirs();
}

File f = new File(root, entry.getName());
FileOutputStream out = new FileOutputStream(f);

if(entry.getName().endsWith(".xml") || entry.getName().endsWith(".vml") || entry.getName().endsWith(".rels")){
try {
XmlObject xml = XmlObject.Factory.parse(zip.getInputStream(entry));
XmlOptions options = new XmlOptions();
options.setSavePrettyPrint();
xml.save(out, options);
} catch (Exception e){
System.err.println("Failed to parse " + entry.getName() + ", dumping raw content");
dump(zip.getInputStream(entry), out);
}
} else {
dump(zip.getInputStream(entry), out);
}
out.close();

}
}

protected static void dump(InputStream is, OutputStream out) throws IOException{
int pos;
byte[] chunk = new byte[2048];
while((pos = is.read(chunk)) > 0) out.write(chunk, 0, pos);

}
}

+ 43
- 42
src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java View File

@@ -1,42 +1,43 @@
/* ====================================================================
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.poi.xssf.dev;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
/**
* Utility which loads a SpreadsheetML file and saves it back.
* This is a handy tool to investigate read-write round trip safety.
*
* @author Yegor Kozlov
*/
public class XSSFSave {
public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
XSSFWorkbook wb = new XSSFWorkbook(args[i]);
int sep = args[i].lastIndexOf('.');
String outfile = args[i].substring(0, sep) + "-save.xls" + (wb.isMacroEnabled() ? "m" : "x");
FileOutputStream out = new FileOutputStream(outfile);
wb.write(out);
out.close();
}
}
}
/* ====================================================================
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.poi.xssf.dev;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;

/**
* Utility which loads a SpreadsheetML file and saves it back.
* This is a handy tool to investigate read-write round trip safety.
*
* @author Yegor Kozlov
*/
public final class XSSFSave {
public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
XSSFWorkbook wb = new XSSFWorkbook(args[i]);

int sep = args[i].lastIndexOf('.');
String outfile = args[i].substring(0, sep) + "-save.xls" + (wb.isMacroEnabled() ? "m" : "x");
FileOutputStream out = new FileOutputStream(outfile);
wb.write(out);
out.close();
}
}

}

+ 37
- 36
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java View File

@@ -1,36 +1,37 @@
/* ====================================================================
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.poi.xssf.usermodel;
/**
* An anchor is what specifics the position of a shape within a client object
* or within another containing shape.
*
* @author Yegor Kozlov
*/
public abstract class XSSFAnchor {
public abstract int getDx1();
public abstract void setDx1( int dx1 );
public abstract int getDy1();
public abstract void setDy1( int dy1 );
public abstract int getDy2();
public abstract void setDy2( int dy2 );
public abstract int getDx2();
public abstract void setDx2( int dx2 );
}
/* ====================================================================
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.poi.xssf.usermodel;

/**
* An anchor is what specifics the position of a shape within a client object
* or within another containing shape.
*
* @author Yegor Kozlov
*/
public abstract class XSSFAnchor {

public abstract int getDx1();
public abstract void setDx1( int dx1 );
public abstract int getDy1();
public abstract void setDy1( int dy1 );
public abstract int getDy2();
public abstract void setDy2( int dy2 );
public abstract int getDx2();
public abstract void setDx2( int dx2 );

}

+ 82
- 81
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java View File

@@ -1,81 +1,82 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
/**
* @author Yegor Kozlov
*/
public class XSSFChildAnchor extends XSSFAnchor {
private CTTransform2D t2d;
public XSSFChildAnchor(int x, int y, int cx, int cy) {
t2d = CTTransform2D.Factory.newInstance();
CTPoint2D off = t2d.addNewOff();
CTPositiveSize2D ext = t2d.addNewExt();
off.setX(x);
off.setY(y);
ext.setCx(Math.abs(cx - x));
ext.setCy(Math.abs(cy - y));
if(x > cx) t2d.setFlipH(true);
if(y > cy) t2d.setFlipV(true);
}
public XSSFChildAnchor(CTTransform2D t2d) {
this.t2d = t2d;
}
public CTTransform2D getCTTransform2D() {
return t2d;
}
public int getDx1() {
return (int)t2d.getOff().getX();
}
public void setDx1(int dx1) {
t2d.getOff().setX(dx1);
}
public int getDy1() {
return (int)t2d.getOff().getY();
}
public void setDy1(int dy1) {
t2d.getOff().setY(dy1);
}
public int getDy2() {
return (int)(getDy1() + t2d.getExt().getCy());
}
public void setDy2(int dy2) {
t2d.getExt().setCy(dy2 - getDy1());
}
public int getDx2() {
return (int)(getDx1() + t2d.getExt().getCx());
}
public void setDx2(int dx2) {
t2d.getExt().setCx(dx2 - getDx1());
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;

/**
* @author Yegor Kozlov
*/
public final class XSSFChildAnchor extends XSSFAnchor {
private CTTransform2D t2d;

public XSSFChildAnchor(int x, int y, int cx, int cy) {
t2d = CTTransform2D.Factory.newInstance();
CTPoint2D off = t2d.addNewOff();
CTPositiveSize2D ext = t2d.addNewExt();

off.setX(x);
off.setY(y);
ext.setCx(Math.abs(cx - x));
ext.setCy(Math.abs(cy - y));
if(x > cx) t2d.setFlipH(true);
if(y > cy) t2d.setFlipV(true);
}

public XSSFChildAnchor(CTTransform2D t2d) {
this.t2d = t2d;
}

public CTTransform2D getCTTransform2D() {
return t2d;
}

public int getDx1() {
return (int)t2d.getOff().getX();
}

public void setDx1(int dx1) {
t2d.getOff().setX(dx1);
}

public int getDy1() {
return (int)t2d.getOff().getY();
}

public void setDy1(int dy1) {
t2d.getOff().setY(dy1);
}

public int getDy2() {
return (int)(getDy1() + t2d.getExt().getCy());
}

public void setDy2(int dy2) {
t2d.getExt().setCy(dy2 - getDy1());
}

public int getDx2() {
return (int)(getDx1() + t2d.getExt().getCx());
}

public void setDx2(int dx2) {
t2d.getExt().setCx(dx2 - getDx1());
}
}

+ 220
- 219
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java View File

@@ -1,219 +1,220 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.apache.poi.ss.usermodel.ClientAnchor;
/**
* A client anchor is attached to an excel worksheet. It anchors against
* top-left and bottom-right cells.
*
* @author Yegor Kozlov
*/
public class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor {
private int anchorType;
/**
* Starting anchor point
*/
private CTMarker cell1;
/**
* Ending anchor point
*/
private CTMarker cell2;
/**
* Creates a new client anchor and defaults all the anchor positions to 0.
*/
public XSSFClientAnchor() {
cell1 = CTMarker.Factory.newInstance();
cell1.setCol(0);
cell1.setColOff(0);
cell1.setRow(0);
cell1.setRowOff(0);
cell2 = CTMarker.Factory.newInstance();
cell2.setCol(0);
cell2.setColOff(0);
cell2.setRow(0);
cell2.setRowOff(0);
}
/**
* Creates a new client anchor and sets the top-left and bottom-right
* coordinates of the anchor.
*
* @param dx1 the x coordinate within the first cell.
* @param dy1 the y coordinate within the first cell.
* @param dx2 the x coordinate within the second cell.
* @param dy2 the y coordinate within the second cell.
* @param col1 the column (0 based) of the first cell.
* @param row1 the row (0 based) of the first cell.
* @param col2 the column (0 based) of the second cell.
* @param row2 the row (0 based) of the second cell.
*/
public XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
this();
cell1.setCol(col1);
cell1.setColOff(dx1);
cell1.setRow(row1);
cell1.setRowOff(dy1);
cell2.setCol(col2);
cell2.setColOff(dx2);
cell2.setRow(row2);
cell2.setRowOff(dy2);
}
/**
* Create XSSFClientAnchor from existing xml beans
*
* @param cell1 starting anchor point
* @param cell2 ending anchor point
*/
protected XSSFClientAnchor(CTMarker cell1, CTMarker cell2) {
this.cell1 = cell1;
this.cell2 = cell2;
}
public short getCol1() {
return (short)cell1.getCol();
}
public void setCol1(int col1) {
cell1.setCol(col1);
}
public short getCol2() {
return (short)cell2.getCol();
}
public void setCol2(int col2) {
cell2.setCol(col2);
}
public int getRow1() {
return cell1.getRow();
}
public void setRow1(int row1) {
cell1.setRow(row1);
}
public int getRow2() {
return cell2.getRow();
}
public void setRow2(int row2) {
cell2.setRow(row2);
}
public int getDx1() {
return (int)cell1.getColOff();
}
public void setDx1(int dx1) {
cell1.setColOff(dx1);
}
public int getDy1() {
return (int)cell1.getRowOff();
}
public void setDy1(int dy1) {
cell1.setRowOff(dy1);
}
public int getDy2() {
return (int)cell2.getRowOff();
}
public void setDy2(int dy2) {
cell2.setRowOff(dy2);
}
public int getDx2() {
return (int)cell2.getColOff();
}
public void setDx2(int dx2) {
cell2.setColOff(dx2);
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof XSSFClientAnchor)) return false;
XSSFClientAnchor anchor = (XSSFClientAnchor) o;
return cell1.toString().equals(anchor.getFrom().toString()) &&
cell2.toString().equals(anchor.getTo().toString()) ;
}
@Override
public String toString(){
return "from : " + cell1.toString() + "; to: " + cell2.toString();
}
/**
* Return starting anchor point
*
* @return starting anchor point
*/
public CTMarker getFrom(){
return cell1;
}
protected void setFrom(CTMarker from){
cell1 = from;
}
/**
* Return ending anchor point
*
* @return ending anchor point
*/
public CTMarker getTo(){
return cell2;
}
protected void setTo(CTMarker to){
cell2 = to;
}
/**
* Sets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
*/
public void setAnchorType( int anchorType )
{
this.anchorType = anchorType;
}
/**
* Gets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
*/
public int getAnchorType()
{
return anchorType;
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.apache.poi.ss.usermodel.ClientAnchor;

/**
* A client anchor is attached to an excel worksheet. It anchors against
* top-left and bottom-right cells.
*
* @author Yegor Kozlov
*/
public final class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor {
private int anchorType;

/**
* Starting anchor point
*/
private CTMarker cell1;

/**
* Ending anchor point
*/
private CTMarker cell2;

/**
* Creates a new client anchor and defaults all the anchor positions to 0.
*/
public XSSFClientAnchor() {
cell1 = CTMarker.Factory.newInstance();
cell1.setCol(0);
cell1.setColOff(0);
cell1.setRow(0);
cell1.setRowOff(0);
cell2 = CTMarker.Factory.newInstance();
cell2.setCol(0);
cell2.setColOff(0);
cell2.setRow(0);
cell2.setRowOff(0);
}

/**
* Creates a new client anchor and sets the top-left and bottom-right
* coordinates of the anchor.
*
* @param dx1 the x coordinate within the first cell.
* @param dy1 the y coordinate within the first cell.
* @param dx2 the x coordinate within the second cell.
* @param dy2 the y coordinate within the second cell.
* @param col1 the column (0 based) of the first cell.
* @param row1 the row (0 based) of the first cell.
* @param col2 the column (0 based) of the second cell.
* @param row2 the row (0 based) of the second cell.
*/
public XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
this();
cell1.setCol(col1);
cell1.setColOff(dx1);
cell1.setRow(row1);
cell1.setRowOff(dy1);
cell2.setCol(col2);
cell2.setColOff(dx2);
cell2.setRow(row2);
cell2.setRowOff(dy2);
}

/**
* Create XSSFClientAnchor from existing xml beans
*
* @param cell1 starting anchor point
* @param cell2 ending anchor point
*/
protected XSSFClientAnchor(CTMarker cell1, CTMarker cell2) {
this.cell1 = cell1;
this.cell2 = cell2;
}

public short getCol1() {
return (short)cell1.getCol();
}

public void setCol1(int col1) {
cell1.setCol(col1);
}

public short getCol2() {
return (short)cell2.getCol();
}

public void setCol2(int col2) {
cell2.setCol(col2);
}

public int getRow1() {
return cell1.getRow();
}

public void setRow1(int row1) {
cell1.setRow(row1);
}

public int getRow2() {
return cell2.getRow();
}

public void setRow2(int row2) {
cell2.setRow(row2);
}

public int getDx1() {
return (int)cell1.getColOff();
}

public void setDx1(int dx1) {
cell1.setColOff(dx1);
}

public int getDy1() {
return (int)cell1.getRowOff();
}

public void setDy1(int dy1) {
cell1.setRowOff(dy1);
}

public int getDy2() {
return (int)cell2.getRowOff();
}

public void setDy2(int dy2) {
cell2.setRowOff(dy2);
}

public int getDx2() {
return (int)cell2.getColOff();
}

public void setDx2(int dx2) {
cell2.setColOff(dx2);
}

@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof XSSFClientAnchor)) return false;

XSSFClientAnchor anchor = (XSSFClientAnchor) o;
return cell1.toString().equals(anchor.getFrom().toString()) &&
cell2.toString().equals(anchor.getTo().toString()) ;

}

@Override
public String toString(){
return "from : " + cell1.toString() + "; to: " + cell2.toString();
}

/**
* Return starting anchor point
*
* @return starting anchor point
*/
public CTMarker getFrom(){
return cell1;
}

protected void setFrom(CTMarker from){
cell1 = from;
}

/**
* Return ending anchor point
*
* @return ending anchor point
*/
public CTMarker getTo(){
return cell2;
}

protected void setTo(CTMarker to){
cell2 = to;
}


/**
* Sets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
*/
public void setAnchorType( int anchorType )
{
this.anchorType = anchorType;
}

/**
* Gets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
*/
public int getAnchorType()
{
return anchorType;
}

}

+ 122
- 121
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java View File

@@ -1,121 +1,122 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
/**
* A connection shape drawing element. A connection shape is a line, etc.
* that connects two other shapes in this drawing.
*
* @author Yegor Kozlov
*/
public class XSSFConnector extends XSSFShape {
private static CTConnector prototype = null;
private CTConnector ctShape;
/**
* Construct a new XSSFConnector object.
*
* @param drawing the XSSFDrawing that owns this shape
* @param ctShape the shape bean that holds all the shape properties
*/
protected XSSFConnector(XSSFDrawing drawing, CTConnector ctShape) {
this.drawing = drawing;
this.ctShape = ctShape;
}
/**
* Initialize default structure of a new auto-shape
*
*/
protected static CTConnector prototype() {
if(prototype == null) {
CTConnector shape = CTConnector.Factory.newInstance();
CTConnectorNonVisual nv = shape.addNewNvCxnSpPr();
CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
nvp.setId(1);
nvp.setName("Shape 1");
nv.addNewCNvCxnSpPr();
CTShapeProperties sp = shape.addNewSpPr();
CTTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);
CTPresetGeometry2D geom = sp.addNewPrstGeom();
geom.setPrst(STShapeType.LINE);
geom.addNewAvLst();
CTShapeStyle style = shape.addNewStyle();
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();
scheme.setVal(STSchemeColorVal.ACCENT_1);
style.getLnRef().setIdx(1);
CTStyleMatrixReference fillref = style.addNewFillRef();
fillref.setIdx(0);
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
CTStyleMatrixReference effectRef = style.addNewEffectRef();
effectRef.setIdx(0);
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
CTFontReference fontRef = style.addNewFontRef();
fontRef.setIdx(STFontCollectionIndex.MINOR);
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.TX_1);
prototype = shape;
}
return prototype;
}
public CTConnector getCTConnector(){
return ctShape;
}
/**
* Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
*
* @return the shape type
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public int getShapeType() {
return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
}
/**
* Sets the shape types.
*
* @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public void setShapeType(int type) {
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
}
protected CTShapeProperties getShapeProperties(){
return ctShape.getSpPr();
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;

/**
* A connection shape drawing element. A connection shape is a line, etc.
* that connects two other shapes in this drawing.
*
* @author Yegor Kozlov
*/
public final class XSSFConnector extends XSSFShape {

private static CTConnector prototype = null;

private CTConnector ctShape;

/**
* Construct a new XSSFConnector object.
*
* @param drawing the XSSFDrawing that owns this shape
* @param ctShape the shape bean that holds all the shape properties
*/
protected XSSFConnector(XSSFDrawing drawing, CTConnector ctShape) {
this.drawing = drawing;
this.ctShape = ctShape;
}

/**
* Initialize default structure of a new auto-shape
*
*/
protected static CTConnector prototype() {
if(prototype == null) {
CTConnector shape = CTConnector.Factory.newInstance();
CTConnectorNonVisual nv = shape.addNewNvCxnSpPr();
CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
nvp.setId(1);
nvp.setName("Shape 1");
nv.addNewCNvCxnSpPr();

CTShapeProperties sp = shape.addNewSpPr();
CTTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);

CTPresetGeometry2D geom = sp.addNewPrstGeom();
geom.setPrst(STShapeType.LINE);
geom.addNewAvLst();

CTShapeStyle style = shape.addNewStyle();
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();
scheme.setVal(STSchemeColorVal.ACCENT_1);
style.getLnRef().setIdx(1);

CTStyleMatrixReference fillref = style.addNewFillRef();
fillref.setIdx(0);
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);

CTStyleMatrixReference effectRef = style.addNewEffectRef();
effectRef.setIdx(0);
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);

CTFontReference fontRef = style.addNewFontRef();
fontRef.setIdx(STFontCollectionIndex.MINOR);
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.TX_1);

prototype = shape;
}
return prototype;
}

public CTConnector getCTConnector(){
return ctShape;
}

/**
* Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
*
* @return the shape type
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public int getShapeType() {
return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
}

/**
* Sets the shape types.
*
* @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public void setShapeType(int type) {
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
}

protected CTShapeProperties getShapeProperties(){
return ctShape.getSpPr();
}

}

+ 248
- 247
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java View File

@@ -1,247 +1,248 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.apache.poi.openxml4j.opc.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.HashMap;
/**
* Represents a SpreadsheetML drawing
*
* @author Yegor Kozlov
*/
public class XSSFDrawing extends POIXMLDocumentPart implements Drawing {
/**
* Root element of the SpreadsheetML Drawing part
*/
private CTDrawing drawing;
private boolean isNew;
/**
* Create a new SpreadsheetML drawing
*
* @see org.apache.poi.xssf.usermodel.XSSFSheet#createDrawingPatriarch()
*/
protected XSSFDrawing() {
super();
drawing = newDrawing();
isNew = true;
}
/**
* Construct a SpreadsheetML drawing from a package part
*
* @param part the package part holding the drawing data,
* the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
* @param rel the package relationship holding this drawing,
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing
*/
protected XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
super(part, rel);
drawing = CTDrawing.Factory.parse(part.getInputStream());
}
/**
* Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects
*
* @return a new CTDrawing bean
*/
private static CTDrawing newDrawing(){
return CTDrawing.Factory.newInstance();
}
/**
* Return the underlying CTDrawing bean, the root element of the SpreadsheetML Drawing part.
*
* @return the underlying CTDrawing bean
*/
public CTDrawing getCTDrawing(){
return drawing;
}
@Override
protected void commit() throws IOException {
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
/*
Saved drawings must have the following namespaces set:
<xdr:wsDr
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
*/
if(isNew) xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr"));
Map map = new HashMap();
map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
xmlOptions.setSaveSuggestedPrefixes(map);
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
drawing.save(out, xmlOptions);
out.close();
}
/**
* Constructs a textbox under the drawing.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created textbox.
*/
public XSSFTextBox createTextbox(XSSFClientAnchor anchor){
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTShape ctShape = ctAnchor.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFTextBox shape = new XSSFTextBox(this, ctShape);
shape.anchor = anchor;
return shape;
}
/**
* Creates a picture.
*
* @param anchor the client anchor describes how this picture is attached to the sheet.
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
*
* @return the newly created picture shape.
*/
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex)
{
PackageRelationship rel = addPictureReference(pictureIndex);
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTPicture ctShape = ctAnchor.addNewPic();
ctShape.set(XSSFPicture.prototype());
XSSFPicture shape = new XSSFPicture(this, ctShape);
shape.anchor = anchor;
shape.setPictureReference(rel);
return shape;
}
public XSSFPicture createPicture(ClientAnchor anchor, int pictureIndex){
return createPicture((XSSFClientAnchor)anchor, pictureIndex);
}
/**
* Add the indexed picture to this drawing relations
*
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
*/
protected PackageRelationship addPictureReference(int pictureIndex){
XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();
XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
PackagePartName ppName = data.getPackagePart().getPartName();
PackageRelationship rel = getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());
addRelation(new XSSFPictureData(data.getPackagePart(), rel));
return rel;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)
{
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTShape ctShape = ctAnchor.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape);
shape.anchor = anchor;
return shape;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public XSSFConnector createConnector(XSSFClientAnchor anchor)
{
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTConnector ctShape = ctAnchor.addNewCxnSp();
ctShape.set(XSSFConnector.prototype());
XSSFConnector shape = new XSSFConnector(this, ctShape);
shape.anchor = anchor;
return shape;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public XSSFShapeGroup createGroup(XSSFClientAnchor anchor)
{
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTGroupShape ctGroup = ctAnchor.addNewGrpSp();
ctGroup.set(XSSFShapeGroup.prototype());
XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup);
shape.anchor = anchor;
return shape;
}
/**
* Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells.
*
* @return a new CTTwoCellAnchor
*/
private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) {
CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();
ctAnchor.setFrom(anchor.getFrom());
ctAnchor.setTo(anchor.getTo());
ctAnchor.addNewClientData();
anchor.setTo(ctAnchor.getTo());
anchor.setFrom(ctAnchor.getFrom());
STEditAs.Enum aditAs;
switch(anchor.getAnchorType()) {
case ClientAnchor.DONT_MOVE_AND_RESIZE: aditAs = STEditAs.ABSOLUTE; break;
case ClientAnchor.MOVE_AND_RESIZE: aditAs = STEditAs.TWO_CELL; break;
case ClientAnchor.MOVE_DONT_RESIZE: aditAs = STEditAs.ONE_CELL; break;
default: aditAs = STEditAs.ONE_CELL;
}
ctAnchor.setEditAs(aditAs);
return ctAnchor;
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.apache.poi.openxml4j.opc.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;

import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.HashMap;

/**
* Represents a SpreadsheetML drawing
*
* @author Yegor Kozlov
*/
public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing {
/**
* Root element of the SpreadsheetML Drawing part
*/
private CTDrawing drawing;
private boolean isNew;

/**
* Create a new SpreadsheetML drawing
*
* @see org.apache.poi.xssf.usermodel.XSSFSheet#createDrawingPatriarch()
*/
protected XSSFDrawing() {
super();
drawing = newDrawing();
isNew = true;
}

/**
* Construct a SpreadsheetML drawing from a package part
*
* @param part the package part holding the drawing data,
* the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
* @param rel the package relationship holding this drawing,
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing
*/
protected XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
super(part, rel);
drawing = CTDrawing.Factory.parse(part.getInputStream());
}

/**
* Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects
*
* @return a new CTDrawing bean
*/
private static CTDrawing newDrawing(){
return CTDrawing.Factory.newInstance();
}

/**
* Return the underlying CTDrawing bean, the root element of the SpreadsheetML Drawing part.
*
* @return the underlying CTDrawing bean
*/
public CTDrawing getCTDrawing(){
return drawing;
}

@Override
protected void commit() throws IOException {
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);

/*
Saved drawings must have the following namespaces set:
<xdr:wsDr
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
*/
if(isNew) xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr"));
Map map = new HashMap();
map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
xmlOptions.setSaveSuggestedPrefixes(map);

PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
drawing.save(out, xmlOptions);
out.close();
}

/**
* Constructs a textbox under the drawing.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created textbox.
*/
public XSSFTextBox createTextbox(XSSFClientAnchor anchor){
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTShape ctShape = ctAnchor.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFTextBox shape = new XSSFTextBox(this, ctShape);
shape.anchor = anchor;
return shape;

}

/**
* Creates a picture.
*
* @param anchor the client anchor describes how this picture is attached to the sheet.
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
*
* @return the newly created picture shape.
*/
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex)
{
PackageRelationship rel = addPictureReference(pictureIndex);

CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTPicture ctShape = ctAnchor.addNewPic();
ctShape.set(XSSFPicture.prototype());

XSSFPicture shape = new XSSFPicture(this, ctShape);
shape.anchor = anchor;
shape.setPictureReference(rel);
return shape;
}

public XSSFPicture createPicture(ClientAnchor anchor, int pictureIndex){
return createPicture((XSSFClientAnchor)anchor, pictureIndex);
}

/**
* Add the indexed picture to this drawing relations
*
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
*/
protected PackageRelationship addPictureReference(int pictureIndex){
XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();
XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
PackagePartName ppName = data.getPackagePart().getPartName();
PackageRelationship rel = getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());
addRelation(new XSSFPictureData(data.getPackagePart(), rel));
return rel;
}

/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)
{
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTShape ctShape = ctAnchor.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape);
shape.anchor = anchor;
return shape;
}

/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public XSSFConnector createConnector(XSSFClientAnchor anchor)
{
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTConnector ctShape = ctAnchor.addNewCxnSp();
ctShape.set(XSSFConnector.prototype());

XSSFConnector shape = new XSSFConnector(this, ctShape);
shape.anchor = anchor;
return shape;
}

/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public XSSFShapeGroup createGroup(XSSFClientAnchor anchor)
{
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
CTGroupShape ctGroup = ctAnchor.addNewGrpSp();
ctGroup.set(XSSFShapeGroup.prototype());

XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup);
shape.anchor = anchor;
return shape;
}

/**
* Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells.
*
* @return a new CTTwoCellAnchor
*/
private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) {
CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();
ctAnchor.setFrom(anchor.getFrom());
ctAnchor.setTo(anchor.getTo());
ctAnchor.addNewClientData();
anchor.setTo(ctAnchor.getTo());
anchor.setFrom(ctAnchor.getFrom());
STEditAs.Enum aditAs;
switch(anchor.getAnchorType()) {
case ClientAnchor.DONT_MOVE_AND_RESIZE: aditAs = STEditAs.ABSOLUTE; break;
case ClientAnchor.MOVE_AND_RESIZE: aditAs = STEditAs.TWO_CELL; break;
case ClientAnchor.MOVE_DONT_RESIZE: aditAs = STEditAs.ONE_CELL; break;
default: aditAs = STEditAs.ONE_CELL;
}
ctAnchor.setEditAs(aditAs);
return ctAnchor;
}
}

+ 180
- 180
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java View File

@@ -1,180 +1,180 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
/**
* Internal POI use only
*
* @author Josh Micich
*/
public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
private final XSSFWorkbook _uBook;
public static XSSFEvaluationWorkbook create(XSSFWorkbook book) {
if (book == null) {
return null;
}
return new XSSFEvaluationWorkbook(book);
}
private XSSFEvaluationWorkbook(XSSFWorkbook book) {
_uBook = book;
}
private int convertFromExternalSheetIndex(int externSheetIndex) {
return externSheetIndex;
}
/**
* @return the sheet index of the sheet with the given external index.
*/
public int convertFromExternSheetIndex(int externSheetIndex) {
return externSheetIndex;
}
/**
* @return the external sheet index of the sheet with the given internal
* index. Used by some of the more obscure formula and named range things.
* Fairly easy on XSSF (we think...) since the internal and external
* indicies are the same
*/
private int convertToExternalSheetIndex(int sheetIndex) {
return sheetIndex;
}
public int getExternalSheetIndex(String sheetName) {
int sheetIndex = _uBook.getSheetIndex(sheetName);
return convertToExternalSheetIndex(sheetIndex);
}
public EvaluationName getName(String name, int sheetIndex) {
for(int i=0; i < _uBook.getNumberOfNames(); i++) {
XSSFName nm = _uBook.getNameAt(i);
String nameText = nm.getNameName();
if (name.equalsIgnoreCase(nameText) && nm.getSheetIndex() == sheetIndex) {
return new Name(_uBook.getNameAt(i), i, this);
}
}
return sheetIndex == -1 ? null : getName(name, -1);
}
public int getSheetIndex(EvaluationSheet evalSheet) {
XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
return _uBook.getSheetIndex(sheet);
}
public String getSheetName(int sheetIndex) {
return _uBook.getSheetName(sheetIndex);
}
public NameXPtg getNameXPtg(String name) {
// may require to return null to make tests pass
throw new RuntimeException("Not implemented yet");
}
public EvaluationSheet getSheet(int sheetIndex) {
return new XSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
}
public ExternalSheet getExternalSheet(int externSheetIndex) {
// TODO Auto-generated method stub
return null;
}
public int getExternalSheetIndex(String workbookName, String sheetName) {
throw new RuntimeException("not implemented yet");
}
public int getSheetIndex(String sheetName) {
return _uBook.getSheetIndex(sheetName);
}
/**
* TODO - figure out what the hell this methods does in
* HSSF...
*/
public String resolveNameXText(NameXPtg n) {
throw new RuntimeException("method not implemented yet");
}
public String getSheetNameByExternSheet(int externSheetIndex) {
int sheetIndex = convertFromExternalSheetIndex(externSheetIndex);
return _uBook.getSheetName(sheetIndex);
}
public String getNameText(NamePtg namePtg) {
return _uBook.getNameAt(namePtg.getIndex()).getNameName();
}
public EvaluationName getName(NamePtg namePtg) {
int ix = namePtg.getIndex();
return new Name(_uBook.getNameAt(ix), ix, this);
}
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
XSSFCell cell = ((XSSFEvaluationCell)evalCell).getXSSFCell();
XSSFEvaluationWorkbook frBook = XSSFEvaluationWorkbook.create(_uBook);
return FormulaParser.parse(cell.getCellFormula(), frBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
}
private static final class Name implements EvaluationName {
private final XSSFName _nameRecord;
private final int _index;
private final FormulaParsingWorkbook _fpBook;
public Name(XSSFName name, int index, FormulaParsingWorkbook fpBook) {
_nameRecord = name;
_index = index;
_fpBook = fpBook;
}
public Ptg[] getNameDefinition() {
return FormulaParser.parse(_nameRecord.getRefersToFormula(), _fpBook, FormulaType.NAMEDRANGE, _nameRecord.getSheetIndex());
}
public String getNameText() {
return _nameRecord.getNameName();
}
public boolean hasFormula() {
// TODO - no idea if this is right
CTDefinedName ctn = _nameRecord.getCTName();
String strVal = ctn.getStringValue();
return !ctn.getFunction() && strVal != null && strVal.length() > 0;
}
public boolean isFunctionName() {
return _nameRecord.isFunctionName();
}
public boolean isRange() {
return hasFormula(); // TODO - is this right?
}
public NamePtg createPtg() {
return new NamePtg(_index);
}
}
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL2007;
}
}
/* ====================================================================
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.poi.xssf.usermodel;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
/**
* Internal POI use only
*
* @author Josh Micich
*/
public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
private final XSSFWorkbook _uBook;
public static XSSFEvaluationWorkbook create(XSSFWorkbook book) {
if (book == null) {
return null;
}
return new XSSFEvaluationWorkbook(book);
}
private XSSFEvaluationWorkbook(XSSFWorkbook book) {
_uBook = book;
}
private int convertFromExternalSheetIndex(int externSheetIndex) {
return externSheetIndex;
}
/**
* @return the sheet index of the sheet with the given external index.
*/
public int convertFromExternSheetIndex(int externSheetIndex) {
return externSheetIndex;
}
/**
* @return the external sheet index of the sheet with the given internal
* index. Used by some of the more obscure formula and named range things.
* Fairly easy on XSSF (we think...) since the internal and external
* indicies are the same
*/
private int convertToExternalSheetIndex(int sheetIndex) {
return sheetIndex;
}
public int getExternalSheetIndex(String sheetName) {
int sheetIndex = _uBook.getSheetIndex(sheetName);
return convertToExternalSheetIndex(sheetIndex);
}
public EvaluationName getName(String name, int sheetIndex) {
for (int i = 0; i < _uBook.getNumberOfNames(); i++) {
XSSFName nm = _uBook.getNameAt(i);
String nameText = nm.getNameName();
if (name.equalsIgnoreCase(nameText) && nm.getSheetIndex() == sheetIndex) {
return new Name(_uBook.getNameAt(i), i, this);
}
}
return sheetIndex == -1 ? null : getName(name, -1);
}
public int getSheetIndex(EvaluationSheet evalSheet) {
XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
return _uBook.getSheetIndex(sheet);
}
public String getSheetName(int sheetIndex) {
return _uBook.getSheetName(sheetIndex);
}
public NameXPtg getNameXPtg(String name) {
// may require to return null to make tests pass
throw new RuntimeException("Not implemented yet");
}
public EvaluationSheet getSheet(int sheetIndex) {
return new XSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
}
public ExternalSheet getExternalSheet(int externSheetIndex) {
// TODO Auto-generated method stub
return null;
}
public int getExternalSheetIndex(String workbookName, String sheetName) {
throw new RuntimeException("not implemented yet");
}
public int getSheetIndex(String sheetName) {
return _uBook.getSheetIndex(sheetName);
}
/**
* TODO - figure out what the hell this methods does in
* HSSF...
*/
public String resolveNameXText(NameXPtg n) {
throw new RuntimeException("method not implemented yet");
}
public String getSheetNameByExternSheet(int externSheetIndex) {
int sheetIndex = convertFromExternalSheetIndex(externSheetIndex);
return _uBook.getSheetName(sheetIndex);
}
public String getNameText(NamePtg namePtg) {
return _uBook.getNameAt(namePtg.getIndex()).getNameName();
}
public EvaluationName getName(NamePtg namePtg) {
int ix = namePtg.getIndex();
return new Name(_uBook.getNameAt(ix), ix, this);
}
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
XSSFCell cell = ((XSSFEvaluationCell)evalCell).getXSSFCell();
XSSFEvaluationWorkbook frBook = XSSFEvaluationWorkbook.create(_uBook);
return FormulaParser.parse(cell.getCellFormula(), frBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
}
private static final class Name implements EvaluationName {
private final XSSFName _nameRecord;
private final int _index;
private final FormulaParsingWorkbook _fpBook;
public Name(XSSFName name, int index, FormulaParsingWorkbook fpBook) {
_nameRecord = name;
_index = index;
_fpBook = fpBook;
}
public Ptg[] getNameDefinition() {
return FormulaParser.parse(_nameRecord.getRefersToFormula(), _fpBook, FormulaType.NAMEDRANGE, _nameRecord.getSheetIndex());
}
public String getNameText() {
return _nameRecord.getNameName();
}
public boolean hasFormula() {
// TODO - no idea if this is right
CTDefinedName ctn = _nameRecord.getCTName();
String strVal = ctn.getStringValue();
return !ctn.getFunction() && strVal != null && strVal.length() > 0;
}
public boolean isFunctionName() {
return _nameRecord.isFunctionName();
}
public boolean isRange() {
return hasFormula(); // TODO - is this right?
}
public NamePtg createPtg() {
return new NamePtg(_index);
}
}
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL2007;
}
}

+ 75
- 74
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java View File

@@ -1,74 +1,75 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLFactory;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;
import java.lang.reflect.Constructor;
/**
* Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
*
* @author Yegor Kozlov
*/
public class XSSFFactory extends POIXMLFactory {
private static POILogger logger = POILogFactory.getLogger(XSSFFactory.class);
private XSSFFactory(){
}
private static final XSSFFactory inst = new XSSFFactory();
public static XSSFFactory getInstance(){
return inst;
}
public POIXMLDocumentPart createDocumentPart(PackageRelationship rel, PackagePart part){
POIXMLRelation descriptor = XSSFRelation.getInstance(rel.getRelationshipType());
if(descriptor == null || descriptor.getRelationClass() == null){
logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());
return new POIXMLDocumentPart(part, rel);
}
try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);
return constructor.newInstance(part, rel);
} catch (Exception e){
throw new POIXMLException(e);
}
}
public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();
return constructor.newInstance();
} catch (Exception e){
throw new POIXMLException(e);
}
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLFactory;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;

import java.lang.reflect.Constructor;

/**
* Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type
*
* @author Yegor Kozlov
*/
public final class XSSFFactory extends POIXMLFactory {
private static POILogger logger = POILogFactory.getLogger(XSSFFactory.class);

private XSSFFactory(){

}

private static final XSSFFactory inst = new XSSFFactory();

public static XSSFFactory getInstance(){
return inst;
}

public POIXMLDocumentPart createDocumentPart(PackageRelationship rel, PackagePart part){
POIXMLRelation descriptor = XSSFRelation.getInstance(rel.getRelationshipType());
if(descriptor == null || descriptor.getRelationClass() == null){
logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());
return new POIXMLDocumentPart(part, rel);
}

try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);
return constructor.newInstance(part, rel);
} catch (Exception e){
throw new POIXMLException(e);
}
}

public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();
return constructor.newInstance();
} catch (Exception e){
throw new POIXMLException(e);
}
}

}

+ 350
- 349
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java View File

@@ -1,349 +1,350 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;
/**
* Represents a picture shape in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public class XSSFPicture extends XSSFShape implements Picture {
private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class);
/**
* Column width measured as the number of characters of the maximum digit width of the
* numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. There are 4 pixels of margin
* padding (two on each side), plus 1 pixel padding for the gridlines.
*
* This value is the same for default font in Office 2007 (Calibry) and Office 2003 and earlier (Arial)
*/
private static float DEFAULT_COLUMN_WIDTH = 9.140625f;
/**
* A default instance of CTShape used for creating new shapes.
*/
private static CTPicture prototype = null;
/**
* This object specifies a picture object and all its properties
*/
private CTPicture ctPicture;
/**
* Construct a new XSSFPicture object. This constructor is called from
* {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)}
*
* @param drawing the XSSFDrawing that owns this picture
*/
protected XSSFPicture(XSSFDrawing drawing, CTPicture ctPicture){
this.drawing = drawing;
this.ctPicture = ctPicture;
}
/**
* Returns a prototype that is used to construct new shapes
*
* @return a prototype that is used to construct new shapes
*/
protected static CTPicture prototype(){
if(prototype == null) {
CTPicture pic = CTPicture.Factory.newInstance();
CTPictureNonVisual nvpr = pic.addNewNvPicPr();
CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr();
nvProps.setId(1);
nvProps.setName("Picture 1");
nvProps.setDescr("Picture");
CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr();
nvPicProps.addNewPicLocks().setNoChangeAspect(true);
CTBlipFillProperties blip = pic.addNewBlipFill();
blip.addNewBlip().setEmbed("");
blip.addNewStretch().addNewFillRect();
CTShapeProperties sppr = pic.addNewSpPr();
CTTransform2D t2d = sppr.addNewXfrm();
CTPositiveSize2D ext = t2d.addNewExt();
//should be original picture width and height expressed in EMUs
ext.setCx(0);
ext.setCy(0);
CTPoint2D off = t2d.addNewOff();
off.setX(0);
off.setY(0);
CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom();
prstGeom.setPrst(STShapeType.RECT);
prstGeom.addNewAvLst();
prototype = pic;
}
return prototype;
}
/**
* Link this shape with the picture data
*
* @param rel relationship referring the picture data
*/
protected void setPictureReference(PackageRelationship rel){
ctPicture.getBlipFill().getBlip().setEmbed(rel.getId());
}
/**
* Return the underlying CTPicture bean that holds all properties for this picture
*
* @return the underlying CTPicture bean
*/
public CTPicture getCTPicture(){
return ctPicture;
}
/**
* Reset the image to the original size.
*/
public void resize(){
resize(1.0);
}
/**
* Reset the image to the original size.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original,
* <code>resize(2.0)</code> resizes to 200% of the original.
*/
public void resize(double scale){
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();
XSSFClientAnchor pref = getPreferredSize(scale);
int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());
anchor.setCol2(col2);
anchor.setDx1(0);
anchor.setDx2(pref.getDx2());
anchor.setRow2(row2);
anchor.setDy1(0);
anchor.setDy2(pref.getDy2());
}
/**
* Calculate the preferred size for this picture.
*
* @return XSSFClientAnchor with the preferred size for this image
*/
public XSSFClientAnchor getPreferredSize(){
return getPreferredSize(1);
}
/**
* Calculate the preferred size for this picture.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* @return XSSFClientAnchor with the preferred size for this image
*/
public XSSFClientAnchor getPreferredSize(double scale){
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();
XSSFPictureData data = getPictureData();
Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType());
double scaledWidth = size.getWidth() * scale;
double scaledHeight = size.getHeight() * scale;
float w = 0;
int col2 = anchor.getCol1();
int dx2 = 0;
if(anchor.getDx1() > 0){
w += getColumnWidthInPixels(col2) - anchor.getDx1();
col2++;
}
for (;;) {
w += getColumnWidthInPixels(col2);
if(w > scaledWidth) break;
col2++;
}
if(w > scaledWidth) {
double cw = getColumnWidthInPixels(col2 + 1);
double delta = w - scaledWidth;
dx2 = (int)(EMU_PER_PIXEL*(cw-delta));
}
anchor.setCol2(col2);
anchor.setDx2(dx2);
double h = 0;
int row2 = anchor.getRow1();
int dy2 = 0;
if(anchor.getDy1() > 0){
h += getRowHeightInPixels(row2) - anchor.getDy1();
row2++;
}
for (;;) {
h += getRowHeightInPixels(row2);
if(h > scaledHeight) break;
row2++;
}
if(h > scaledHeight) {
double ch = getRowHeightInPixels(row2 + 1);
double delta = h - scaledHeight;
dy2 = (int)(EMU_PER_PIXEL*(ch-delta));
}
anchor.setRow2(row2);
anchor.setDy2(dy2);
CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt();
size2d.setCx((long)(scaledWidth*EMU_PER_PIXEL));
size2d.setCy((long)(scaledHeight*EMU_PER_PIXEL));
return anchor;
}
private float getColumnWidthInPixels(int columnIndex){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
CTCol col = sheet.getColumnHelper().getColumn(columnIndex, false);
double numChars = col == null || !col.isSetWidth() ? DEFAULT_COLUMN_WIDTH : col.getWidth();
return (float)numChars*XSSFWorkbook.DEFAULT_CHARACTER_WIDTH;
}
private float getRowHeightInPixels(int rowIndex){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
XSSFRow row = sheet.getRow(rowIndex);
float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints();
return height*PIXEL_DPI/POINT_DPI;
}
/**
* Return the dimension of this image
*
* @param part the package part holding raw picture data
* @param type type of the picture: {@link Workbook#PICTURE_TYPE_JPEG},
* {@link Workbook#PICTURE_TYPE_PNG} or {@link Workbook#PICTURE_TYPE_DIB}
*
* @return image dimension in pixels
*/
protected static Dimension getImageDimension(PackagePart part, int type){
Dimension size = new Dimension();
switch (type){
//we can calculate the preferred size only for JPEG, PNG and BMP
//other formats like WMF, EMF and PICT are not supported in Java
case Workbook.PICTURE_TYPE_JPEG:
case Workbook.PICTURE_TYPE_PNG:
case Workbook.PICTURE_TYPE_DIB:
try {
//read the image using javax.imageio.*
ImageInputStream iis = ImageIO.createImageInputStream( part.getInputStream() );
Iterator i = ImageIO.getImageReaders( iis );
ImageReader r = (ImageReader) i.next();
r.setInput( iis );
BufferedImage img = r.read(0);
int[] dpi = getResolution(r);
//if DPI is zero then assume standard 96 DPI
//since cannot divide by zero
if (dpi[0] == 0) dpi[0] = PIXEL_DPI;
if (dpi[1] == 0) dpi[1] = PIXEL_DPI;
size.width = img.getWidth()*PIXEL_DPI/dpi[0];
size.height = img.getHeight()*PIXEL_DPI/dpi[1];
} catch (IOException e){
//silently return if ImageIO failed to read the image
logger.log(POILogger.WARN, e);
}
break;
default:
logger.log(POILogger.WARN, "Only JPEG, PNG and DIB pictures can be automatically sized");
}
return size;
}
/**
* The metadata of PNG and JPEG can contain the width of a pixel in millimeters.
* Return the the "effective" dpi calculated as <code>25.4/HorizontalPixelSize</code>
* and <code>25.4/VerticalPixelSize</code>. Where 25.4 is the number of mm in inch.
*
* @return array of two elements: <code>{horisontalPdi, verticalDpi}</code>.
* {96, 96} is the default.
*/
protected static int[] getResolution(ImageReader r) throws IOException {
int hdpi = PIXEL_DPI, vdpi = PIXEL_DPI;
double mm2inch = 25.4;
NodeList lst;
Element node = (Element)r.getImageMetadata(0).getAsTree("javax_imageio_1.0");
lst = node.getElementsByTagName("HorizontalPixelSize");
if(lst != null && lst.getLength() == 1) hdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));
lst = node.getElementsByTagName("VerticalPixelSize");
if(lst != null && lst.getLength() == 1) vdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));
return new int[]{hdpi, vdpi};
}
/**
* Return picture data for this shape
*
* @return picture data for this shape
*/
public XSSFPictureData getPictureData() {
String blipId = ctPicture.getBlipFill().getBlip().getEmbed();
for (POIXMLDocumentPart part : getDrawing().getRelations()) {
if(part.getPackageRelationship().getId().equals(blipId)){
return (XSSFPictureData)part;
}
}
logger.log(POILogger.WARN, "Picture data was not found for blipId=" + blipId);
return null;
}
protected CTShapeProperties getShapeProperties(){
return ctPicture.getSpPr();
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;

/**
* Represents a picture shape in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public final class XSSFPicture extends XSSFShape implements Picture {
private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class);

/**
* Column width measured as the number of characters of the maximum digit width of the
* numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. There are 4 pixels of margin
* padding (two on each side), plus 1 pixel padding for the gridlines.
*
* This value is the same for default font in Office 2007 (Calibry) and Office 2003 and earlier (Arial)
*/
private static float DEFAULT_COLUMN_WIDTH = 9.140625f;

/**
* A default instance of CTShape used for creating new shapes.
*/
private static CTPicture prototype = null;

/**
* This object specifies a picture object and all its properties
*/
private CTPicture ctPicture;

/**
* Construct a new XSSFPicture object. This constructor is called from
* {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)}
*
* @param drawing the XSSFDrawing that owns this picture
*/
protected XSSFPicture(XSSFDrawing drawing, CTPicture ctPicture){
this.drawing = drawing;
this.ctPicture = ctPicture;
}

/**
* Returns a prototype that is used to construct new shapes
*
* @return a prototype that is used to construct new shapes
*/
protected static CTPicture prototype(){
if(prototype == null) {
CTPicture pic = CTPicture.Factory.newInstance();
CTPictureNonVisual nvpr = pic.addNewNvPicPr();
CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr();
nvProps.setId(1);
nvProps.setName("Picture 1");
nvProps.setDescr("Picture");
CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr();
nvPicProps.addNewPicLocks().setNoChangeAspect(true);

CTBlipFillProperties blip = pic.addNewBlipFill();
blip.addNewBlip().setEmbed("");
blip.addNewStretch().addNewFillRect();

CTShapeProperties sppr = pic.addNewSpPr();
CTTransform2D t2d = sppr.addNewXfrm();
CTPositiveSize2D ext = t2d.addNewExt();
//should be original picture width and height expressed in EMUs
ext.setCx(0);
ext.setCy(0);

CTPoint2D off = t2d.addNewOff();
off.setX(0);
off.setY(0);

CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom();
prstGeom.setPrst(STShapeType.RECT);
prstGeom.addNewAvLst();

prototype = pic;
}
return prototype;
}

/**
* Link this shape with the picture data
*
* @param rel relationship referring the picture data
*/
protected void setPictureReference(PackageRelationship rel){
ctPicture.getBlipFill().getBlip().setEmbed(rel.getId());
}

/**
* Return the underlying CTPicture bean that holds all properties for this picture
*
* @return the underlying CTPicture bean
*/
public CTPicture getCTPicture(){
return ctPicture;
}

/**
* Reset the image to the original size.
*/
public void resize(){
resize(1.0);
}

/**
* Reset the image to the original size.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original,
* <code>resize(2.0)</code> resizes to 200% of the original.
*/
public void resize(double scale){
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();

XSSFClientAnchor pref = getPreferredSize(scale);

int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());

anchor.setCol2(col2);
anchor.setDx1(0);
anchor.setDx2(pref.getDx2());

anchor.setRow2(row2);
anchor.setDy1(0);
anchor.setDy2(pref.getDy2());
}

/**
* Calculate the preferred size for this picture.
*
* @return XSSFClientAnchor with the preferred size for this image
*/
public XSSFClientAnchor getPreferredSize(){
return getPreferredSize(1);
}

/**
* Calculate the preferred size for this picture.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* @return XSSFClientAnchor with the preferred size for this image
*/
public XSSFClientAnchor getPreferredSize(double scale){
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();

XSSFPictureData data = getPictureData();
Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType());
double scaledWidth = size.getWidth() * scale;
double scaledHeight = size.getHeight() * scale;

float w = 0;
int col2 = anchor.getCol1();
int dx2 = 0;
if(anchor.getDx1() > 0){
w += getColumnWidthInPixels(col2) - anchor.getDx1();
col2++;
}

for (;;) {
w += getColumnWidthInPixels(col2);
if(w > scaledWidth) break;
col2++;
}

if(w > scaledWidth) {
double cw = getColumnWidthInPixels(col2 + 1);
double delta = w - scaledWidth;
dx2 = (int)(EMU_PER_PIXEL*(cw-delta));
}
anchor.setCol2(col2);
anchor.setDx2(dx2);

double h = 0;
int row2 = anchor.getRow1();
int dy2 = 0;

if(anchor.getDy1() > 0){
h += getRowHeightInPixels(row2) - anchor.getDy1();
row2++;
}

for (;;) {
h += getRowHeightInPixels(row2);
if(h > scaledHeight) break;
row2++;
}

if(h > scaledHeight) {
double ch = getRowHeightInPixels(row2 + 1);
double delta = h - scaledHeight;
dy2 = (int)(EMU_PER_PIXEL*(ch-delta));
}
anchor.setRow2(row2);
anchor.setDy2(dy2);

CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt();
size2d.setCx((long)(scaledWidth*EMU_PER_PIXEL));
size2d.setCy((long)(scaledHeight*EMU_PER_PIXEL));

return anchor;
}

private float getColumnWidthInPixels(int columnIndex){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();

CTCol col = sheet.getColumnHelper().getColumn(columnIndex, false);
double numChars = col == null || !col.isSetWidth() ? DEFAULT_COLUMN_WIDTH : col.getWidth();

return (float)numChars*XSSFWorkbook.DEFAULT_CHARACTER_WIDTH;
}

private float getRowHeightInPixels(int rowIndex){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();

XSSFRow row = sheet.getRow(rowIndex);
float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints();
return height*PIXEL_DPI/POINT_DPI;
}

/**
* Return the dimension of this image
*
* @param part the package part holding raw picture data
* @param type type of the picture: {@link Workbook#PICTURE_TYPE_JPEG},
* {@link Workbook#PICTURE_TYPE_PNG} or {@link Workbook#PICTURE_TYPE_DIB}
*
* @return image dimension in pixels
*/
protected static Dimension getImageDimension(PackagePart part, int type){
Dimension size = new Dimension();

switch (type){
//we can calculate the preferred size only for JPEG, PNG and BMP
//other formats like WMF, EMF and PICT are not supported in Java
case Workbook.PICTURE_TYPE_JPEG:
case Workbook.PICTURE_TYPE_PNG:
case Workbook.PICTURE_TYPE_DIB:
try {
//read the image using javax.imageio.*
ImageInputStream iis = ImageIO.createImageInputStream( part.getInputStream() );
Iterator i = ImageIO.getImageReaders( iis );
ImageReader r = (ImageReader) i.next();
r.setInput( iis );
BufferedImage img = r.read(0);

int[] dpi = getResolution(r);

//if DPI is zero then assume standard 96 DPI
//since cannot divide by zero
if (dpi[0] == 0) dpi[0] = PIXEL_DPI;
if (dpi[1] == 0) dpi[1] = PIXEL_DPI;

size.width = img.getWidth()*PIXEL_DPI/dpi[0];
size.height = img.getHeight()*PIXEL_DPI/dpi[1];

} catch (IOException e){
//silently return if ImageIO failed to read the image
logger.log(POILogger.WARN, e);
}

break;
default:
logger.log(POILogger.WARN, "Only JPEG, PNG and DIB pictures can be automatically sized");
}
return size;
}

/**
* The metadata of PNG and JPEG can contain the width of a pixel in millimeters.
* Return the the "effective" dpi calculated as <code>25.4/HorizontalPixelSize</code>
* and <code>25.4/VerticalPixelSize</code>. Where 25.4 is the number of mm in inch.
*
* @return array of two elements: <code>{horisontalPdi, verticalDpi}</code>.
* {96, 96} is the default.
*/
protected static int[] getResolution(ImageReader r) throws IOException {
int hdpi = PIXEL_DPI, vdpi = PIXEL_DPI;
double mm2inch = 25.4;

NodeList lst;
Element node = (Element)r.getImageMetadata(0).getAsTree("javax_imageio_1.0");
lst = node.getElementsByTagName("HorizontalPixelSize");
if(lst != null && lst.getLength() == 1) hdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));

lst = node.getElementsByTagName("VerticalPixelSize");
if(lst != null && lst.getLength() == 1) vdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));

return new int[]{hdpi, vdpi};
}

/**
* Return picture data for this shape
*
* @return picture data for this shape
*/
public XSSFPictureData getPictureData() {
String blipId = ctPicture.getBlipFill().getBlip().getEmbed();
for (POIXMLDocumentPart part : getDrawing().getRelations()) {
if(part.getPackageRelationship().getId().equals(blipId)){
return (XSSFPictureData)part;
}
}
logger.log(POILogger.WARN, "Picture data was not found for blipId=" + blipId);
return null;
}

protected CTShapeProperties getShapeProperties(){
return ctPicture.getSpPr();
}

}

+ 151
- 150
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java View File

@@ -1,150 +1,151 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
/**
* Represents a shape in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public abstract class XSSFShape {
public static final int EMU_PER_PIXEL = 9525;
public static final int EMU_PER_POINT = 12700;
public static final int POINT_DPI = 72;
public static final int PIXEL_DPI = 96;
/**
* Parent drawing
*/
protected XSSFDrawing drawing;
/**
* The parent shape, always not-null for shapes in groups
*/
protected XSSFShapeGroup parent;
/**
* anchor that is used by this shape
*/
protected XSSFAnchor anchor;
/**
* Return the drawing that owns this shape
*
* @return the parent drawing that owns this shape
*/
public XSSFDrawing getDrawing(){
return drawing;
}
/**
* Gets the parent shape.
*/
public XSSFShapeGroup getParent()
{
return parent;
}
/**
* @return the anchor that is used by this shape.
*/
public XSSFAnchor getAnchor()
{
return anchor;
}
/**
* Returns xml bean with shape properties.
*
* @return xml bean with shape properties.
*/
protected abstract CTShapeProperties getShapeProperties();
/**
* Whether this shape is not filled with a color
*
* @return true if this shape is not filled with a color.
*/
public boolean isNoFill() {
return getShapeProperties().isSetNoFill();
}
/**
* Sets whether this shape is filled or transparent.
*
* @param noFill if true then no fill will be applied to the shape element.
*/
public void setNoFill(boolean noFill) {
CTShapeProperties props = getShapeProperties();
//unset solid and pattern fills if they are set
if (props.isSetPattFill()) props.unsetPattFill();
if (props.isSetSolidFill()) props.unsetSolidFill();
props.setNoFill(CTNoFillProperties.Factory.newInstance());
}
/**
* Sets the color used to fill this shape using the solid fill pattern.
*/
public void setFillColor(int red, int green, int blue) {
CTShapeProperties props = getShapeProperties();
CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});
fill.setSrgbClr(rgb);
}
/**
* The color applied to the lines of this shape.
*/
public void setLineStyleColor( int red, int green, int blue ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});
fill.setSrgbClr(rgb);
}
/**
* Specifies the width to be used for the underline stroke.
*
* @param lineWidth width in points
*/
public void setLineWidth( double lineWidth ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
ln.setW((int)(lineWidth*EMU_PER_POINT));
}
/**
* Sets the line style.
*
* @param lineStyle
*/
public void setLineStyle( int lineStyle ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
CTPresetLineDashProperties dashStyle = CTPresetLineDashProperties.Factory.newInstance();
dashStyle.setVal(STPresetLineDashVal.Enum.forInt(lineStyle+1));
ln.setPrstDash(dashStyle);
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.main.*;

/**
* Represents a shape in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public abstract class XSSFShape {
public static final int EMU_PER_PIXEL = 9525;
public static final int EMU_PER_POINT = 12700;

public static final int POINT_DPI = 72;
public static final int PIXEL_DPI = 96;

/**
* Parent drawing
*/
protected XSSFDrawing drawing;

/**
* The parent shape, always not-null for shapes in groups
*/
protected XSSFShapeGroup parent;

/**
* anchor that is used by this shape
*/
protected XSSFAnchor anchor;

/**
* Return the drawing that owns this shape
*
* @return the parent drawing that owns this shape
*/
public XSSFDrawing getDrawing(){
return drawing;
}

/**
* Gets the parent shape.
*/
public XSSFShapeGroup getParent()
{
return parent;
}

/**
* @return the anchor that is used by this shape.
*/
public XSSFAnchor getAnchor()
{
return anchor;
}

/**
* Returns xml bean with shape properties.
*
* @return xml bean with shape properties.
*/
protected abstract CTShapeProperties getShapeProperties();

/**
* Whether this shape is not filled with a color
*
* @return true if this shape is not filled with a color.
*/
public boolean isNoFill() {
return getShapeProperties().isSetNoFill();
}

/**
* Sets whether this shape is filled or transparent.
*
* @param noFill if true then no fill will be applied to the shape element.
*/
public void setNoFill(boolean noFill) {
CTShapeProperties props = getShapeProperties();
//unset solid and pattern fills if they are set
if (props.isSetPattFill()) props.unsetPattFill();
if (props.isSetSolidFill()) props.unsetSolidFill();

props.setNoFill(CTNoFillProperties.Factory.newInstance());
}

/**
* Sets the color used to fill this shape using the solid fill pattern.
*/
public void setFillColor(int red, int green, int blue) {
CTShapeProperties props = getShapeProperties();
CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});
fill.setSrgbClr(rgb);
}

/**
* The color applied to the lines of this shape.
*/
public void setLineStyleColor( int red, int green, int blue ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});
fill.setSrgbClr(rgb);
}

/**
* Specifies the width to be used for the underline stroke.
*
* @param lineWidth width in points
*/
public void setLineWidth( double lineWidth ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
ln.setW((int)(lineWidth*EMU_PER_POINT));
}

/**
* Sets the line style.
*
* @param lineStyle
*/
public void setLineStyle( int lineStyle ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
CTPresetLineDashProperties dashStyle = CTPresetLineDashProperties.Factory.newInstance();
dashStyle.setVal(STPresetLineDashVal.Enum.forInt(lineStyle+1));
ln.setPrstDash(dashStyle);
}

}

+ 186
- 185
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java View File

@@ -1,185 +1,186 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.apache.poi.openxml4j.opc.PackageRelationship;
/**
* This object specifies a group shape that represents many shapes grouped together. This shape is to be treated
* just as if it were a regular shape but instead of being described by a single geometry it is made up of all the
* shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are
* specified just as they normally would.
*
* @author Yegor Kozlov
*/
public class XSSFShapeGroup extends XSSFShape {
private static CTGroupShape prototype = null;
private CTGroupShape ctGroup;
/**
* Construct a new XSSFSimpleShape object.
*
* @param drawing the XSSFDrawing that owns this shape
* @param ctGroup the XML bean that stores this group content
*/
protected XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) {
this.drawing = drawing;
this.ctGroup = ctGroup;
}
/**
* Initialize default structure of a new shape group
*/
protected static CTGroupShape prototype() {
if (prototype == null) {
CTGroupShape shape = CTGroupShape.Factory.newInstance();
CTGroupShapeNonVisual nv = shape.addNewNvGrpSpPr();
CTNonVisualDrawingProps nvpr = nv.addNewCNvPr();
nvpr.setId(0);
nvpr.setName("Group 0");
nv.addNewCNvGrpSpPr();
CTGroupShapeProperties sp = shape.addNewGrpSpPr();
CTGroupTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);
CTPositiveSize2D p3 = t2d.addNewChExt();
p3.setCx(0);
p3.setCy(0);
CTPoint2D p4 = t2d.addNewChOff();
p4.setX(0);
p4.setY(0);
prototype = shape;
}
return prototype;
}
/**
* Constructs a textbox.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created textbox.
*/
public XSSFTextBox createTextbox(XSSFChildAnchor anchor){
CTShape ctShape = ctGroup.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created shape.
*/
public XSSFSimpleShape createSimpleShape(XSSFChildAnchor anchor) {
CTShape ctShape = ctGroup.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created shape.
*/
public XSSFConnector createConnector(XSSFChildAnchor anchor) {
CTConnector ctShape = ctGroup.addNewCxnSp();
ctShape.set(XSSFConnector.prototype());
XSSFConnector shape = new XSSFConnector(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTConnector().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;
}
/**
* Creates a picture.
*
* @param anchor the client anchor describes how this picture is attached to the sheet.
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link XSSFWorkbook#getAllPictures()} .
* @return the newly created picture shape.
*/
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) {
PackageRelationship rel = getDrawing().addPictureReference(pictureIndex);
CTPicture ctShape = ctGroup.addNewPic();
ctShape.set(XSSFPicture.prototype());
XSSFPicture shape = new XSSFPicture(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.setPictureReference(rel);
return shape;
}
public CTGroupShape getCTGroupShape() {
return ctGroup;
}
/**
* Sets the coordinate space of this group. All children are constrained
* to these coordinates.
*/
public void setCoordinates(int x1, int y1, int x2, int y2) {
CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm();
CTPoint2D off = t2d.getOff();
off.setX(x1);
off.setY(y1);
CTPositiveSize2D ext = t2d.getExt();
ext.setCx(x2);
ext.setCy(y2);
CTPoint2D chOff = t2d.getChOff();
chOff.setX(x1);
chOff.setY(y1);
CTPositiveSize2D chExt = t2d.getChExt();
chExt.setCx(x2);
chExt.setCy(y2);
}
protected CTShapeProperties getShapeProperties() {
throw new IllegalStateException("Not supported for shape group");
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.apache.poi.openxml4j.opc.PackageRelationship;

/**
* This object specifies a group shape that represents many shapes grouped together. This shape is to be treated
* just as if it were a regular shape but instead of being described by a single geometry it is made up of all the
* shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are
* specified just as they normally would.
*
* @author Yegor Kozlov
*/
public final class XSSFShapeGroup extends XSSFShape {
private static CTGroupShape prototype = null;

private CTGroupShape ctGroup;

/**
* Construct a new XSSFSimpleShape object.
*
* @param drawing the XSSFDrawing that owns this shape
* @param ctGroup the XML bean that stores this group content
*/
protected XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) {
this.drawing = drawing;
this.ctGroup = ctGroup;
}

/**
* Initialize default structure of a new shape group
*/
protected static CTGroupShape prototype() {
if (prototype == null) {
CTGroupShape shape = CTGroupShape.Factory.newInstance();

CTGroupShapeNonVisual nv = shape.addNewNvGrpSpPr();
CTNonVisualDrawingProps nvpr = nv.addNewCNvPr();
nvpr.setId(0);
nvpr.setName("Group 0");
nv.addNewCNvGrpSpPr();
CTGroupShapeProperties sp = shape.addNewGrpSpPr();
CTGroupTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);
CTPositiveSize2D p3 = t2d.addNewChExt();
p3.setCx(0);
p3.setCy(0);
CTPoint2D p4 = t2d.addNewChOff();
p4.setX(0);
p4.setY(0);

prototype = shape;
}
return prototype;
}

/**
* Constructs a textbox.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created textbox.
*/
public XSSFTextBox createTextbox(XSSFChildAnchor anchor){
CTShape ctShape = ctGroup.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());

XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;

}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created shape.
*/
public XSSFSimpleShape createSimpleShape(XSSFChildAnchor anchor) {
CTShape ctShape = ctGroup.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());

XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;
}

/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created shape.
*/
public XSSFConnector createConnector(XSSFChildAnchor anchor) {
CTConnector ctShape = ctGroup.addNewCxnSp();
ctShape.set(XSSFConnector.prototype());

XSSFConnector shape = new XSSFConnector(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTConnector().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;
}

/**
* Creates a picture.
*
* @param anchor the client anchor describes how this picture is attached to the sheet.
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link XSSFWorkbook#getAllPictures()} .
* @return the newly created picture shape.
*/
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) {
PackageRelationship rel = getDrawing().addPictureReference(pictureIndex);

CTPicture ctShape = ctGroup.addNewPic();
ctShape.set(XSSFPicture.prototype());

XSSFPicture shape = new XSSFPicture(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.setPictureReference(rel);
return shape;
}

public CTGroupShape getCTGroupShape() {
return ctGroup;
}

/**
* Sets the coordinate space of this group. All children are constrained
* to these coordinates.
*/
public void setCoordinates(int x1, int y1, int x2, int y2) {
CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm();
CTPoint2D off = t2d.getOff();
off.setX(x1);
off.setY(y1);
CTPositiveSize2D ext = t2d.getExt();
ext.setCx(x2);
ext.setCy(y2);

CTPoint2D chOff = t2d.getChOff();
chOff.setX(x1);
chOff.setY(y1);
CTPositiveSize2D chExt = t2d.getChExt();
chExt.setCx(x2);
chExt.setCy(y2);
}

protected CTShapeProperties getShapeProperties() {
throw new IllegalStateException("Not supported for shape group");
}

}

+ 180
- 179
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java View File

@@ -1,179 +1,180 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
/**
* Represents a shape with a predefined geometry in a SpreadsheetML drawing.
* Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}
*
* @author Yegor Kozlov
*/
public class XSSFSimpleShape extends XSSFShape {
/**
* A default instance of CTShape used for creating new shapes.
*/
private static CTShape prototype = null;
/**
* Xml bean that stores properties of this shape
*/
private CTShape ctShape;
protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) {
this.drawing = drawing;
this.ctShape = ctShape;
}
/**
* Prototype with the default structure of a new auto-shape.
*/
protected static CTShape prototype() {
if(prototype == null) {
CTShape shape = CTShape.Factory.newInstance();
CTShapeNonVisual nv = shape.addNewNvSpPr();
CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
nvp.setId(1);
nvp.setName("Shape 1");
nv.addNewCNvSpPr();
CTShapeProperties sp = shape.addNewSpPr();
CTTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);
CTPresetGeometry2D geom = sp.addNewPrstGeom();
geom.setPrst(STShapeType.RECT);
geom.addNewAvLst();
CTShapeStyle style = shape.addNewStyle();
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();
scheme.setVal(STSchemeColorVal.ACCENT_1);
scheme.addNewShade().setVal(50000);
style.getLnRef().setIdx(2);
CTStyleMatrixReference fillref = style.addNewFillRef();
fillref.setIdx(1);
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
CTStyleMatrixReference effectRef = style.addNewEffectRef();
effectRef.setIdx(0);
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
CTFontReference fontRef = style.addNewFontRef();
fontRef.setIdx(STFontCollectionIndex.MINOR);
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);
CTTextBody body = shape.addNewTxBody();
CTTextBodyProperties bodypr = body.addNewBodyPr();
bodypr.setAnchor(STTextAnchoringType.CTR);
bodypr.setRtlCol(false);
CTTextParagraph p = body.addNewP();
p.addNewPPr().setAlgn(STTextAlignType.CTR);
CTTextCharacterProperties endPr = p.addNewEndParaRPr();
endPr.setLang("en-US");
endPr.setSz(1100);
body.addNewLstStyle();
prototype = shape;
}
return prototype;
}
public CTShape getCTShape(){
return ctShape;
}
/**
* Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
*
* @return the shape type
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public int getShapeType() {
return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
}
/**
* Sets the shape types.
*
* @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public void setShapeType(int type) {
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
}
protected CTShapeProperties getShapeProperties(){
return ctShape.getSpPr();
}
public void setText(XSSFRichTextString str){
XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent();
str.setStylesTableReference(wb.getStylesSource());
CTTextParagraph p = CTTextParagraph.Factory.newInstance();
if(str.numFormattingRuns() == 0){
CTRegularTextRun r = p.addNewR();
CTTextCharacterProperties rPr = r.addNewRPr();
rPr.setLang("en-US");
rPr.setSz(1100);
r.setT(str.getString());
} else {
for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) {
CTRElt lt = str.getCTRst().getRArray(i);
CTRPrElt ltPr = lt.getRPr();
CTRegularTextRun r = p.addNewR();
CTTextCharacterProperties rPr = r.addNewRPr();
rPr.setLang("en-US");
applyAttributes(ltPr, rPr);
r.setT(lt.getT());
}
}
ctShape.getTxBody().setPArray(new CTTextParagraph[]{p});
}
/**
*
* CTRPrElt --> CTFont adapter
*/
private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){
if(pr.sizeOfBArray() > 0) rPr.setB(pr.getBArray(0).getVal());
//if(pr.sizeOfUArray() > 0) rPr.setU(pr.getUArray(0).getVal());
if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal());
CTTextFont rFont = rPr.addNewLatin();
rFont.setTypeface(pr.sizeOfRFontArray() > 0 ? pr.getRFontArray(0).getVal() : "Arial");
}
}
/* ====================================================================
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.poi.xssf.usermodel;

import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;

/**
* Represents a shape with a predefined geometry in a SpreadsheetML drawing.
* Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}
*
* @author Yegor Kozlov
*/
public class XSSFSimpleShape extends XSSFShape { // TODO - instantiable superclass
/**
* A default instance of CTShape used for creating new shapes.
*/
private static CTShape prototype = null;

/**
* Xml bean that stores properties of this shape
*/
private CTShape ctShape;

protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) {
this.drawing = drawing;
this.ctShape = ctShape;
}

/**
* Prototype with the default structure of a new auto-shape.
*/
protected static CTShape prototype() {
if(prototype == null) {
CTShape shape = CTShape.Factory.newInstance();

CTShapeNonVisual nv = shape.addNewNvSpPr();
CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
nvp.setId(1);
nvp.setName("Shape 1");
nv.addNewCNvSpPr();

CTShapeProperties sp = shape.addNewSpPr();
CTTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);

CTPresetGeometry2D geom = sp.addNewPrstGeom();
geom.setPrst(STShapeType.RECT);
geom.addNewAvLst();

CTShapeStyle style = shape.addNewStyle();
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();
scheme.setVal(STSchemeColorVal.ACCENT_1);
scheme.addNewShade().setVal(50000);
style.getLnRef().setIdx(2);

CTStyleMatrixReference fillref = style.addNewFillRef();
fillref.setIdx(1);
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);

CTStyleMatrixReference effectRef = style.addNewEffectRef();
effectRef.setIdx(0);
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);

CTFontReference fontRef = style.addNewFontRef();
fontRef.setIdx(STFontCollectionIndex.MINOR);
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);

CTTextBody body = shape.addNewTxBody();
CTTextBodyProperties bodypr = body.addNewBodyPr();
bodypr.setAnchor(STTextAnchoringType.CTR);
bodypr.setRtlCol(false);
CTTextParagraph p = body.addNewP();
p.addNewPPr().setAlgn(STTextAlignType.CTR);
CTTextCharacterProperties endPr = p.addNewEndParaRPr();
endPr.setLang("en-US");
endPr.setSz(1100);

body.addNewLstStyle();

prototype = shape;
}
return prototype;
}

public CTShape getCTShape(){
return ctShape;
}

/**
* Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
*
* @return the shape type
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public int getShapeType() {
return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
}

/**
* Sets the shape types.
*
* @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
* @see org.apache.poi.ss.usermodel.ShapeTypes
*/
public void setShapeType(int type) {
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
}

protected CTShapeProperties getShapeProperties(){
return ctShape.getSpPr();
}

public void setText(XSSFRichTextString str){

XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent();
str.setStylesTableReference(wb.getStylesSource());

CTTextParagraph p = CTTextParagraph.Factory.newInstance();
if(str.numFormattingRuns() == 0){
CTRegularTextRun r = p.addNewR();
CTTextCharacterProperties rPr = r.addNewRPr();
rPr.setLang("en-US");
rPr.setSz(1100);
r.setT(str.getString());

} else {
for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) {
CTRElt lt = str.getCTRst().getRArray(i);
CTRPrElt ltPr = lt.getRPr();

CTRegularTextRun r = p.addNewR();
CTTextCharacterProperties rPr = r.addNewRPr();
rPr.setLang("en-US");

applyAttributes(ltPr, rPr);

r.setT(lt.getT());
}
}
ctShape.getTxBody().setPArray(new CTTextParagraph[]{p});

}

/**
*
* CTRPrElt --> CTFont adapter
*/
private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){

if(pr.sizeOfBArray() > 0) rPr.setB(pr.getBArray(0).getVal());
//if(pr.sizeOfUArray() > 0) rPr.setU(pr.getUArray(0).getVal());
if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal());

CTTextFont rFont = rPr.addNewLatin();
rFont.setTypeface(pr.sizeOfRFontArray() > 0 ? pr.getRFontArray(0).getVal() : "Arial");
}
}

+ 32
- 32
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java View File

@@ -1,32 +1,32 @@
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
/**
* Represents a text box in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public class XSSFTextBox extends XSSFSimpleShape {
protected XSSFTextBox(XSSFDrawing drawing, CTShape ctShape) {
super(drawing, ctShape);
}
}
/* ====================================================================
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.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
/**
* Represents a text box in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public final class XSSFTextBox extends XSSFSimpleShape {
protected XSSFTextBox(XSSFDrawing drawing, CTShape ctShape) {
super(drawing, ctShape);
}
}

+ 190
- 189
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java View File

@@ -1,189 +1,190 @@
/* ====================================================================
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.poi.xssf.usermodel.helpers;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.hssf.record.formula.FormulaShifter;
import org.apache.poi.hssf.record.formula.Ptg;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
import java.util.List;
import java.util.ArrayList;
/**
* @author Yegor Kozlov
*/
public class XSSFRowShifter {
private final XSSFSheet sheet;
public XSSFRowShifter(XSSFSheet sh) {
sheet = sh;
}
/**
* Shift merged regions
*
* @param startRow the row to start shifting
* @param endRow the row to end shifting
* @param n the number of rows to shift
* @return an array of affected cell regions
*/
public List<CellRangeAddress> shiftMerged(int startRow, int endRow, int n) {
List<CellRangeAddress> shiftedRegions = new ArrayList<CellRangeAddress>();
//move merged regions completely if they fall within the new region boundaries when they are shifted
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress merged = sheet.getMergedRegion(i);
boolean inStart = (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
boolean inEnd = (merged.getFirstRow() <= endRow || merged.getLastRow() <= endRow);
//don't check if it's not within the shifted area
if (!inStart || !inEnd) {
continue;
}
//only shift if the region outside the shifted rows is not merged too
if (!containsCell(merged, startRow - 1, 0) && !containsCell(merged, endRow + 1, 0)) {
merged.setFirstRow(merged.getFirstRow() + n);
merged.setLastRow(merged.getLastRow() + n);
//have to remove/add it back
shiftedRegions.add(merged);
sheet.removeMergedRegion(i);
i = i - 1; // we have to back up now since we removed one
}
}
//read so it doesn't get shifted again
for (CellRangeAddress region : shiftedRegions) {
sheet.addMergedRegion(region);
}
return shiftedRegions;
}
/**
* Check if the row and column are in the specified cell range
*
* @param cr the cell range to check in
* @param rowIx the row to check
* @param colIx the column to check
* @return true if the range contains the cell [rowIx,colIx]
*/
private static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) {
if (cr.getFirstRow() <= rowIx && cr.getLastRow() >= rowIx
&& cr.getFirstColumn() <= colIx && cr.getLastColumn() >= colIx) {
return true;
}
return false;
}
/**
* Updated named ranges
*/
public void updateNamedRanges(FormulaShifter shifter) {
XSSFWorkbook wb = sheet.getWorkbook();
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
for (int i = 0; i < wb.getNumberOfNames(); i++) {
XSSFName name = wb.getNameAt(i);
String formula = name.getRefersToFormula();
int sheetIndex = name.getSheetIndex();
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.NAMEDRANGE, sheetIndex);
if (shifter.adjustFormula(ptgs, sheetIndex)) {
String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
name.setRefersToFormula(shiftedFmla);
}
}
}
/**
* Update formulas.
*/
public void updateFormulas(FormulaShifter shifter) {
//update formulas on the parent sheet
updateSheetFormulas(sheet, shifter);
//update formulas on other sheets
XSSFWorkbook wb = sheet.getWorkbook();
for (XSSFSheet sh : wb) {
if (sheet == sh) continue;
updateSheetFormulas(sh, shifter);
}
}
private void updateSheetFormulas(XSSFSheet sh, FormulaShifter shifter) {
for (Row r : sh) {
XSSFRow row = (XSSFRow) r;
updateRowFormulas(row, shifter);
}
}
private void updateRowFormulas(XSSFRow row, FormulaShifter shifter) {
for (Cell c : row) {
XSSFCell cell = (XSSFCell) c;
CTCell ctCell = cell.getCTCell();
if (ctCell.isSetF()) {
CTCellFormula f = ctCell.getF();
String formula = f.getStringValue();
if (formula.length() > 0) {
String shiftedFormula = shiftFormula(row, formula, shifter);
if (shiftedFormula != null) {
f.setStringValue(shiftedFormula);
}
}
if (f.isSetRef()) { //Range of cells which the formula applies to.
String ref = f.getRef();
String shiftedRef = shiftFormula(row, ref, shifter);
if (shiftedRef != null) f.setRef(shiftedRef);
}
}
}
}
/**
* Shift a formula using the supplied FormulaShifter
*
* @param row the row of the cell this formula belongs to. Used to get a reference to the parent workbook.
* @param formula the formula to shift
* @param shifter the FormulaShifter object that operates on the parsed formula tokens
* @return the shifted formula if the formula was changed,
* <code>null</code> if the formula wasn't modified
*/
private static String shiftFormula(XSSFRow row, String formula, FormulaShifter shifter) {
XSSFSheet sheet = row.getSheet();
XSSFWorkbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
String shiftedFmla = null;
if (shifter.adjustFormula(ptgs, sheetIndex)) {
shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
}
return shiftedFmla;
}
}
/* ====================================================================
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.poi.xssf.usermodel.helpers;

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.hssf.record.formula.FormulaShifter;
import org.apache.poi.hssf.record.formula.Ptg;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;

import java.util.List;
import java.util.ArrayList;

/**
* @author Yegor Kozlov
*/
public final class XSSFRowShifter {
private final XSSFSheet sheet;

public XSSFRowShifter(XSSFSheet sh) {
sheet = sh;
}

/**
* Shift merged regions
*
* @param startRow the row to start shifting
* @param endRow the row to end shifting
* @param n the number of rows to shift
* @return an array of affected cell regions
*/
public List<CellRangeAddress> shiftMerged(int startRow, int endRow, int n) {
List<CellRangeAddress> shiftedRegions = new ArrayList<CellRangeAddress>();
//move merged regions completely if they fall within the new region boundaries when they are shifted
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress merged = sheet.getMergedRegion(i);

boolean inStart = (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
boolean inEnd = (merged.getFirstRow() <= endRow || merged.getLastRow() <= endRow);

//don't check if it's not within the shifted area
if (!inStart || !inEnd) {
continue;
}

//only shift if the region outside the shifted rows is not merged too
if (!containsCell(merged, startRow - 1, 0) && !containsCell(merged, endRow + 1, 0)) {
merged.setFirstRow(merged.getFirstRow() + n);
merged.setLastRow(merged.getLastRow() + n);
//have to remove/add it back
shiftedRegions.add(merged);
sheet.removeMergedRegion(i);
i = i - 1; // we have to back up now since we removed one
}
}

//read so it doesn't get shifted again
for (CellRangeAddress region : shiftedRegions) {
sheet.addMergedRegion(region);
}
return shiftedRegions;
}

/**
* Check if the row and column are in the specified cell range
*
* @param cr the cell range to check in
* @param rowIx the row to check
* @param colIx the column to check
* @return true if the range contains the cell [rowIx,colIx]
*/
private static boolean containsCell(CellRangeAddress cr, int rowIx, int colIx) {
if (cr.getFirstRow() <= rowIx && cr.getLastRow() >= rowIx
&& cr.getFirstColumn() <= colIx && cr.getLastColumn() >= colIx) {
return true;
}
return false;
}

/**
* Updated named ranges
*/
public void updateNamedRanges(FormulaShifter shifter) {
XSSFWorkbook wb = sheet.getWorkbook();
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
for (int i = 0; i < wb.getNumberOfNames(); i++) {
XSSFName name = wb.getNameAt(i);
String formula = name.getRefersToFormula();
int sheetIndex = name.getSheetIndex();

Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.NAMEDRANGE, sheetIndex);
if (shifter.adjustFormula(ptgs, sheetIndex)) {
String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
name.setRefersToFormula(shiftedFmla);
}

}
}

/**
* Update formulas.
*/
public void updateFormulas(FormulaShifter shifter) {
//update formulas on the parent sheet
updateSheetFormulas(sheet, shifter);

//update formulas on other sheets
XSSFWorkbook wb = sheet.getWorkbook();
for (XSSFSheet sh : wb) {
if (sheet == sh) continue;
updateSheetFormulas(sh, shifter);
}
}

private void updateSheetFormulas(XSSFSheet sh, FormulaShifter shifter) {
for (Row r : sh) {
XSSFRow row = (XSSFRow) r;
updateRowFormulas(row, shifter);
}
}

private void updateRowFormulas(XSSFRow row, FormulaShifter shifter) {
for (Cell c : row) {
XSSFCell cell = (XSSFCell) c;

CTCell ctCell = cell.getCTCell();
if (ctCell.isSetF()) {
CTCellFormula f = ctCell.getF();
String formula = f.getStringValue();
if (formula.length() > 0) {
String shiftedFormula = shiftFormula(row, formula, shifter);
if (shiftedFormula != null) {
f.setStringValue(shiftedFormula);
}
}

if (f.isSetRef()) { //Range of cells which the formula applies to.
String ref = f.getRef();
String shiftedRef = shiftFormula(row, ref, shifter);
if (shiftedRef != null) f.setRef(shiftedRef);
}
}

}
}

/**
* Shift a formula using the supplied FormulaShifter
*
* @param row the row of the cell this formula belongs to. Used to get a reference to the parent workbook.
* @param formula the formula to shift
* @param shifter the FormulaShifter object that operates on the parsed formula tokens
* @return the shifted formula if the formula was changed,
* <code>null</code> if the formula wasn't modified
*/
private static String shiftFormula(XSSFRow row, String formula, FormulaShifter shifter) {
XSSFSheet sheet = row.getSheet();
XSSFWorkbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
String shiftedFmla = null;
if (shifter.adjustFormula(ptgs, sheetIndex)) {
shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
}
return shiftedFmla;
}

}

+ 626
- 626
src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java
File diff suppressed because it is too large
View File


+ 66
- 65
src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java View File

@@ -1,65 +1,66 @@
/* ====================================================================
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.poi.xwpf.usermodel;
import java.util.Map;
import java.util.HashMap;
/**
* Specifies all types of alignment which are available to be applied to objects in a
* WordprocessingML document
*
* @author Yegor Kozlov
*/
public enum ParagraphAlignment {
//YK: TODO document each alignment option
LEFT(1),
CENTER(2),
RIGHT(3),
BOTH(4),
MEDIUM_KASHIDA(5),
DISTRIBUTE(6),
NUM_TAB(7),
HIGH_KASHIDA(8),
LOW_KASHIDA(9),
THAI_DISTRIBUTE(10);
private final int value;
private ParagraphAlignment(int val){
value = val;
}
public int getValue(){
return value;
}
private static Map<Integer, ParagraphAlignment> imap = new HashMap<Integer, ParagraphAlignment>();
static{
for (ParagraphAlignment p : values()) {
imap.put(p.getValue(), p);
}
}
public static ParagraphAlignment valueOf(int type){
ParagraphAlignment err = imap.get(type);
if(err == null) throw new IllegalArgumentException("Unknown paragraph alignment: " + type);
return err;
}
}
/* ====================================================================
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.poi.xwpf.usermodel;

import java.util.Map;
import java.util.HashMap;

/**
* Specifies all types of alignment which are available to be applied to objects in a
* WordprocessingML document
*
* @author Yegor Kozlov
*/
public enum ParagraphAlignment {
//YK: TODO document each alignment option

LEFT(1),
CENTER(2),
RIGHT(3),
BOTH(4),
MEDIUM_KASHIDA(5),
DISTRIBUTE(6),
NUM_TAB(7),
HIGH_KASHIDA(8),
LOW_KASHIDA(9),
THAI_DISTRIBUTE(10);

private final int value;

private ParagraphAlignment(int val){
value = val;
}

public int getValue(){
return value;
}

private static Map<Integer, ParagraphAlignment> imap = new HashMap<Integer, ParagraphAlignment>();
static{
for (ParagraphAlignment p : values()) {
imap.put(p.getValue(), p);
}
}

public static ParagraphAlignment valueOf(int type){
ParagraphAlignment err = imap.get(type);
if(err == null) throw new IllegalArgumentException("Unknown paragraph alignment: " + type);
return err;
}

}

+ 74
- 73
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java View File

@@ -1,73 +1,74 @@
/* ====================================================================
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.poi.xwpf.usermodel;
import org.apache.poi.POIXMLFactory;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;
import java.lang.reflect.Constructor;
/**
* @author Yegor Kozlov
*/
public class XWPFFactory extends POIXMLFactory {
private static POILogger logger = POILogFactory.getLogger(XWPFFactory.class);
private XWPFFactory(){
}
private static final XWPFFactory inst = new XWPFFactory();
public static XWPFFactory getInstance(){
return inst;
}
public POIXMLDocumentPart createDocumentPart(PackageRelationship rel, PackagePart part){
POIXMLRelation descriptor = XWPFRelation.getInstance(rel.getRelationshipType());
if(descriptor == null || descriptor.getRelationClass() == null){
logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());
return new POIXMLDocumentPart(part, rel);
}
try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);
return constructor.newInstance(part, rel);
} catch (Exception e){
throw new POIXMLException(e);
}
}
public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();
return constructor.newInstance();
} catch (Exception e){
throw new POIXMLException(e);
}
}
}
/* ====================================================================
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.poi.xwpf.usermodel;

import org.apache.poi.POIXMLFactory;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart;

import java.lang.reflect.Constructor;

/**
* @author Yegor Kozlov
*/
public final class XWPFFactory extends POIXMLFactory {

private static POILogger logger = POILogFactory.getLogger(XWPFFactory.class);

private XWPFFactory(){

}

private static final XWPFFactory inst = new XWPFFactory();

public static XWPFFactory getInstance(){
return inst;
}

public POIXMLDocumentPart createDocumentPart(PackageRelationship rel, PackagePart part){
POIXMLRelation descriptor = XWPFRelation.getInstance(rel.getRelationshipType());
if(descriptor == null || descriptor.getRelationClass() == null){
logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType());
return new POIXMLDocumentPart(part, rel);
}

try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class);
return constructor.newInstance(part, rel);
} catch (Exception e){
throw new POIXMLException(e);
}
}

public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){
try {
Class cls = descriptor.getRelationClass();
Constructor<? extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor();
return constructor.newInstance();
} catch (Exception e){
throw new POIXMLException(e);
}
}

}

+ 110
- 109
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java View File

@@ -1,109 +1,110 @@
/* ====================================================================
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.poi.xwpf.usermodel;
import org.apache.poi.POIXMLRelation;
import org.apache.poi.POIXMLDocumentPart;
import java.util.Map;
import java.util.HashMap;
/**
* @author Yegor Kozlov
*/
public class XWPFRelation extends POIXMLRelation {
/**
* A map to lookup POIXMLRelation by its relation type
*/
protected static Map<String, XWPFRelation> _table = new HashMap<String, XWPFRelation>();
public static final XWPFRelation DOCUMENT = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
"/word/document.xml",
null
);
public static final XWPFRelation FONT_TABLE = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
"/word/fontTable.xml",
null
);
public static final XWPFRelation SETTINGS = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
"/word/settings.xml",
null
);
public static final XWPFRelation STYLES = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
"/word/styles.xml",
null
);
public static final XWPFRelation WEB_SETTINGS = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings",
"/word/webSettings.xml",
null
);
public static final XWPFRelation HEADER = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
"/word/header#.xml",
null
);
public static final XWPFRelation FOOTER = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
"/word/footer#.xml",
null
);
public static final XWPFRelation HYPERLINK = new XWPFRelation(
null,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
null,
null
);
public static final XWPFRelation COMMENT = new XWPFRelation(
null,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
null,
null
);
private XWPFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
super(type, rel, defaultName, cls);
if (cls != null && !_table.containsKey(rel)) _table.put(rel, this);
}
/**
* Get POIXMLRelation by relation type
*
* @param rel relation type, for example,
* <code>http://schemas.openxmlformats.org/officeDocument/2006/relationships/image</code>
* @return registered POIXMLRelation or null if not found
*/
public static XWPFRelation getInstance(String rel) {
return _table.get(rel);
}
}
/* ====================================================================
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.poi.xwpf.usermodel;

import org.apache.poi.POIXMLRelation;
import org.apache.poi.POIXMLDocumentPart;

import java.util.Map;
import java.util.HashMap;

/**
* @author Yegor Kozlov
*/
public final class XWPFRelation extends POIXMLRelation {

/**
* A map to lookup POIXMLRelation by its relation type
*/
protected static Map<String, XWPFRelation> _table = new HashMap<String, XWPFRelation>();


public static final XWPFRelation DOCUMENT = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
"/word/document.xml",
null
);
public static final XWPFRelation FONT_TABLE = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
"/word/fontTable.xml",
null
);
public static final XWPFRelation SETTINGS = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
"/word/settings.xml",
null
);
public static final XWPFRelation STYLES = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
"/word/styles.xml",
null
);
public static final XWPFRelation WEB_SETTINGS = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings",
"/word/webSettings.xml",
null
);
public static final XWPFRelation HEADER = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
"/word/header#.xml",
null
);
public static final XWPFRelation FOOTER = new XWPFRelation(
"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
"/word/footer#.xml",
null
);
public static final XWPFRelation HYPERLINK = new XWPFRelation(
null,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
null,
null
);
public static final XWPFRelation COMMENT = new XWPFRelation(
null,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
null,
null
);


private XWPFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
super(type, rel, defaultName, cls);

if (cls != null && !_table.containsKey(rel)) _table.put(rel, this);
}

/**
* Get POIXMLRelation by relation type
*
* @param rel relation type, for example,
* <code>http://schemas.openxmlformats.org/officeDocument/2006/relationships/image</code>
* @return registered POIXMLRelation or null if not found
*/
public static XWPFRelation getInstance(String rel) {
return _table.get(rel);
}

}

Loading…
Cancel
Save