diff options
56 files changed, 7716 insertions, 7713 deletions
diff --git a/src/ooxml/java/org/apache/poi/POIXMLException.java b/src/ooxml/java/org/apache/poi/POIXMLException.java index 1a4bf7ff1d..0c5ad44a51 100755 --- a/src/ooxml/java/org/apache/poi/POIXMLException.java +++ b/src/ooxml/java/org/apache/poi/POIXMLException.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/POIXMLFactory.java b/src/ooxml/java/org/apache/poi/POIXMLFactory.java index f10cf0ca01..d8b3111908 100755 --- a/src/ooxml/java/org/apache/poi/POIXMLFactory.java +++ b/src/ooxml/java/org/apache/poi/POIXMLFactory.java @@ -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); +} diff --git a/src/ooxml/java/org/apache/poi/POIXMLRelation.java b/src/ooxml/java/org/apache/poi/POIXMLRelation.java index a11c49ca18..e89090960c 100755 --- a/src/ooxml/java/org/apache/poi/POIXMLRelation.java +++ b/src/ooxml/java/org/apache/poi/POIXMLRelation.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java index 689f8f33db..13ed195c22 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java index 9e45ccf4b3..814edd1179 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidOperationException.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java index d2fa0e1446..09979d96de 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java index c68d85ecbb..7e95153fa6 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JRuntimeException.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java index 8b946e6d08..cd7b456941 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java @@ -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 +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java index b6c5b30f7d..583b5c51de 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java index 72241b38d9..40141befc8 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java index 9671d3a67a..3754ce8a9a 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java index 0e15332f32..bc994e0f1c 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java @@ -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 +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java index a40f4ac436..2568822285 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java @@ -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 +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java index 5f53781eb8..d1adc519fc 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java @@ -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"; +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java index 54021302bf..e4ecbd44b8 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java index f1cc7fdaad..4b1a8448d9 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java @@ -1,509 +1,506 @@ -/* ====================================================================
- 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.net.URI;
-import java.net.URISyntaxException;
-
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
-
-/**
- * An immutable Open Packaging Convention compliant part name.
- *
- * @author Julien Chable
- * @version 0.1
- *
- * @see <a href="http://www.ietf.org/rfc/rfc3986.txt">http://www.ietf.org/rfc/rfc3986.txt</a>
- */
-public final class PackagePartName implements Comparable<PackagePartName> {
-
- /**
- * Part name stored as an URI.
- */
- private URI partNameURI;
-
- /*
- * URI Characters definition (RFC 3986)
- */
-
- /**
- * Reserved characters for sub delimitations.
- */
- private static String[] RFC3986_PCHAR_SUB_DELIMS = { "!", "$", "&", "'",
- "(", ")", "*", "+", ",", ";", "=" };
-
- /**
- * Unreserved character (+ ALPHA & DIGIT).
- */
- private static String[] RFC3986_PCHAR_UNRESERVED_SUP = { "-", ".", "_", "~" };
-
- /**
- * Authorized reserved characters for pChar.
- */
- private static String[] RFC3986_PCHAR_AUTHORIZED_SUP = { ":", "@" };
-
- /**
- * Flag to know if this part name is from a relationship part name.
- */
- private boolean isRelationship;
-
- /**
- * Constructor. Makes a ValidPartName object from a java.net.URI
- *
- * @param uri
- * The URI to validate and to transform into ValidPartName.
- * @param checkConformance
- * Flag to specify if the contructor have to validate the OPC
- * conformance. Must be always <code>true</code> except for
- * special URI like '/' which is needed for internal use by
- * OpenXML4J but is not valid.
- * @throws InvalidFormatException
- * Throw if the specified part name is not conform to Open
- * Packaging Convention specifications.
- * @see java.net.URI
- */
- PackagePartName(URI uri, boolean checkConformance)
- throws InvalidFormatException {
- if (checkConformance) {
- throwExceptionIfInvalidPartUri(uri);
- } else {
- if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(uri)) {
- throw new OpenXML4JRuntimeException(
- "OCP conformance must be check for ALL part name except special cases : ['/']");
- }
- }
- this.partNameURI = uri;
- this.isRelationship = isRelationshipPartURI(this.partNameURI);
- }
-
- /**
- * Constructor. Makes a ValidPartName object from a String part name.
- *
- * @param partName
- * Part name to valid and to create.
- * @param checkConformance
- * Flag to specify if the contructor have to validate the OPC
- * conformance. Must be always <code>true</code> except for
- * special URI like '/' which is needed for internal use by
- * OpenXML4J but is not valid.
- * @throws InvalidFormatException
- * Throw if the specified part name is not conform to Open
- * Packaging Convention specifications.
- */
- PackagePartName(String partName, boolean checkConformance)
- throws InvalidFormatException {
- URI partURI;
- try {
- partURI = new URI(partName);
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(
- "partName argmument is not a valid OPC part name !");
- }
-
- if (checkConformance) {
- throwExceptionIfInvalidPartUri(partURI);
- } else {
- if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(partURI)) {
- throw new OpenXML4JRuntimeException(
- "OCP conformance must be check for ALL part name except special cases : ['/']");
- }
- }
- this.partNameURI = partURI;
- this.isRelationship = isRelationshipPartURI(this.partNameURI);
- }
-
- /**
- * Check if the specified part name is a relationship part name.
- *
- * @param partUri
- * The URI to check.
- * @return <code>true</code> if this part name respect the relationship
- * part naming convention else <code>false</code>.
- */
- private boolean isRelationshipPartURI(URI partUri) {
- if (partUri == null)
- throw new IllegalArgumentException("partUri");
-
- return partUri.getPath().matches(
- "^.*/" + PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME + "/.*\\"
- + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME
- + "$");
- }
-
- /**
- * Know if this part name is a relationship part name.
- *
- * @return <code>true</code> if this part name respect the relationship
- * part naming convention else <code>false</code>.
- */
- public boolean isRelationshipPartURI() {
- return this.isRelationship;
- }
-
- /**
- * Throws an exception (of any kind) if the specified part name does not
- * follow the Open Packaging Convention specifications naming rules.
- *
- * @param partUri
- * The part name to check.
- * @throws Exception
- * Throws if the part name is invalid.
- */
- private static void throwExceptionIfInvalidPartUri(URI partUri)
- throws InvalidFormatException {
- if (partUri == null)
- throw new IllegalArgumentException("partUri");
- // Check if the part name URI is empty [M1.1]
- throwExceptionIfEmptyURI(partUri);
-
- // Check if the part name URI is absolute
- throwExceptionIfAbsoluteUri(partUri);
-
- // Check if the part name URI starts with a forward slash [M1.4]
- throwExceptionIfPartNameNotStartsWithForwardSlashChar(partUri);
-
- // Check if the part name URI ends with a forward slash [M1.5]
- throwExceptionIfPartNameEndsWithForwardSlashChar(partUri);
-
- // Check if the part name does not have empty segments. [M1.3]
- // Check if a segment ends with a dot ('.') character. [M1.9]
- throwExceptionIfPartNameHaveInvalidSegments(partUri);
- }
-
- /**
- * Throws an exception if the specified URI is empty. [M1.1]
- *
- * @param partURI
- * Part URI to check.
- * @throws InvalidFormatException
- * If the specified URI is empty.
- */
- private static void throwExceptionIfEmptyURI(URI partURI)
- throws InvalidFormatException {
- if (partURI == null)
- throw new IllegalArgumentException("partURI");
-
- String uriPath = partURI.getPath();
- if (uriPath.length() == 0
- || ((uriPath.length() == 1) && (uriPath.charAt(0) == PackagingURIHelper.FORWARD_SLASH_CHAR)))
- throw new InvalidFormatException(
- "A part name shall not be empty [M1.1]: "
- + partURI.getPath());
- }
-
- /**
- * Throws an exception if the part name has empty segments. [M1.3]
- *
- * Throws an exception if a segment any characters other than pchar
- * characters. [M1.6]
- *
- * Throws an exception if a segment contain percent-encoded forward slash
- * ('/'), or backward slash ('\') characters. [M1.7]
- *
- * Throws an exception if a segment contain percent-encoded unreserved
- * characters. [M1.8]
- *
- * Throws an exception if the specified part name's segments end with a dot
- * ('.') character. [M1.9]
- *
- * Throws an exception if a segment doesn't include at least one non-dot
- * character. [M1.10]
- *
- * @param partUri
- * The part name to check.
- * @throws InvalidFormatException
- * if the specified URI contain an empty segments or if one the
- * segments contained in the part name, ends with a dot ('.')
- * character.
- */
- private static void throwExceptionIfPartNameHaveInvalidSegments(URI partUri)
- throws InvalidFormatException {
- if (partUri == null || "".equals(partUri)) {
- throw new IllegalArgumentException("partUri");
- }
-
- // Split the URI into several part and analyze each
- String[] segments = partUri.toASCIIString().split("/");
- if (segments.length <= 1 || !segments[0].equals(""))
- throw new InvalidFormatException(
- "A part name shall not have empty segments [M1.3]: "
- + partUri.getPath());
-
- for (int i = 1; i < segments.length; ++i) {
- String seg = segments[i];
- if (seg == null || "".equals(seg)) {
- throw new InvalidFormatException(
- "A part name shall not have empty segments [M1.3]: "
- + partUri.getPath());
- }
-
- if (seg.endsWith(".")) {
- throw new InvalidFormatException(
- "A segment shall not end with a dot ('.') character [M1.9]: "
- + partUri.getPath());
- }
-
- if ("".equals(seg.replaceAll("\\\\.", ""))) {
- // Normally will never been invoked with the previous
- // implementation rule [M1.9]
- throw new InvalidFormatException(
- "A segment shall include at least one non-dot character. [M1.10]: "
- + partUri.getPath());
- }
-
- /*
- * Check for rule M1.6, M1.7, M1.8
- */
- checkPCharCompliance(seg);
- }
- }
-
- /**
- * Throws an exception if a segment any characters other than pchar
- * characters. [M1.6]
- *
- * Throws an exception if a segment contain percent-encoded forward slash
- * ('/'), or backward slash ('\') characters. [M1.7]
- *
- * Throws an exception if a segment contain percent-encoded unreserved
- * characters. [M1.8]
- *
- * @param segment
- * The segment to check
- */
- private static void checkPCharCompliance(String segment)
- throws InvalidFormatException {
- boolean errorFlag;
- for (int i = 0; i < segment.length(); ++i) {
- char c = segment.charAt(i);
- errorFlag = true;
-
- /* Check rule M1.6 */
-
- // Check for digit or letter
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
- || (c >= '0' && c <= '9')) {
- errorFlag = false;
- } else {
- // Check "-", ".", "_", "~"
- for (int j = 0; j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) {
- if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) {
- errorFlag = false;
- break;
- }
- }
-
- // Check ":", "@"
- for (int j = 0; errorFlag
- && j < RFC3986_PCHAR_AUTHORIZED_SUP.length; ++j) {
- if (c == RFC3986_PCHAR_AUTHORIZED_SUP[j].charAt(0)) {
- errorFlag = false;
- }
- }
-
- // Check "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
- for (int j = 0; errorFlag
- && j < RFC3986_PCHAR_SUB_DELIMS.length; ++j) {
- if (c == RFC3986_PCHAR_SUB_DELIMS[j].charAt(0)) {
- errorFlag = false;
- }
- }
- }
-
- if (errorFlag && c == '%') {
- // We certainly found an encoded character, check for length
- // now ( '%' HEXDIGIT HEXDIGIT)
- if (((segment.length() - i) < 2)) {
- throw new InvalidFormatException("The segment " + segment
- + " contain invalid encoded character !");
- }
-
- // If not percent encoded character error occur then reset the
- // flag -> the character is valid
- errorFlag = false;
-
- // Decode the encoded character
- char decodedChar = (char) Integer.parseInt(segment.substring(
- i + 1, i + 3), 16);
- i += 2;
-
- /* Check rule M1.7 */
- if (decodedChar == '/' || decodedChar == '\\')
- throw new InvalidFormatException(
- "A segment shall not contain percent-encoded forward slash ('/'), or backward slash ('\') characters. [M1.7]");
-
- /* Check rule M1.8 */
-
- // Check for unreserved character like define in RFC3986
- if ((decodedChar >= 'A' && decodedChar <= 'Z')
- || (decodedChar >= 'a' && decodedChar <= 'z')
- || (decodedChar >= '0' && decodedChar <= '9'))
- errorFlag = true;
-
- // Check for unreserved character "-", ".", "_", "~"
- for (int j = 0; !errorFlag
- && j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) {
- if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) {
- errorFlag = true;
- break;
- }
- }
- if (errorFlag)
- throw new InvalidFormatException(
- "A segment shall not contain percent-encoded unreserved characters. [M1.8]");
- }
-
- if (errorFlag)
- throw new InvalidFormatException(
- "A segment shall not hold any characters other than pchar characters. [M1.6]");
- }
- }
-
- /**
- * Throws an exception if the specified part name doesn't start with a
- * forward slash character '/'. [M1.4]
- *
- * @param partUri
- * The part name to check.
- * @throws InvalidFormatException
- * If the specified part name doesn't start with a forward slash
- * character '/'.
- */
- private static void throwExceptionIfPartNameNotStartsWithForwardSlashChar(
- URI partUri) throws InvalidFormatException {
- String uriPath = partUri.getPath();
- if (uriPath.length() > 0
- && uriPath.charAt(0) != PackagingURIHelper.FORWARD_SLASH_CHAR)
- throw new InvalidFormatException(
- "A part name shall start with a forward slash ('/') character [M1.4]: "
- + partUri.getPath());
- }
-
- /**
- * Throws an exception if the specified part name ends with a forwar slash
- * character '/'. [M1.5]
- *
- * @param partUri
- * The part name to check.
- * @throws InvalidFormatException
- * If the specified part name ends with a forwar slash character
- * '/'.
- */
- private static void throwExceptionIfPartNameEndsWithForwardSlashChar(
- URI partUri) throws InvalidFormatException {
- String uriPath = partUri.getPath();
- if (uriPath.length() > 0
- && uriPath.charAt(uriPath.length() - 1) == PackagingURIHelper.FORWARD_SLASH_CHAR)
- throw new InvalidFormatException(
- "A part name shall not have a forward slash as the last character [M1.5]: "
- + partUri.getPath());
- }
-
- /**
- * Throws an exception if the specified URI is absolute.
- *
- * @param partUri
- * The URI to check.
- * @throws InvalidFormatException
- * Throws if the specified URI is absolute.
- */
- private static void throwExceptionIfAbsoluteUri(URI partUri)
- throws InvalidFormatException {
- if (partUri.isAbsolute())
- throw new InvalidFormatException("Absolute URI forbidden: "
- + partUri);
- }
-
- /**
- * Compare two part name following the rule M1.12 :
- *
- * Part name equivalence is determined by comparing part names as
- * case-insensitive ASCII strings. Packages shall not contain equivalent
- * part names and package implementers shall neither create nor recognize
- * packages with equivalent part names. [M1.12]
- */
- public int compareTo(PackagePartName otherPartName) {
- if (otherPartName == null)
- return -1;
- return this.partNameURI.toASCIIString().toLowerCase().compareTo(
- otherPartName.partNameURI.toASCIIString().toLowerCase());
- }
-
- /**
- * Retrieves the extension of the part name if any. If there is no extension
- * returns an empty String. Example : '/document/content.xml' => 'xml'
- *
- * @return The extension of the part name.
- */
- public String getExtension() {
- String fragment = this.partNameURI.getPath();
- if (fragment.length() > 0) {
- int i = fragment.lastIndexOf(".");
- if (i > -1)
- return fragment.substring(i + 1);
- }
- return "";
- }
-
- /**
- * Get this part name.
- *
- * @return The name of this part name.
- */
- public String getName() {
- return this.partNameURI.toASCIIString();
- }
-
- /**
- * Part name equivalence is determined by comparing part names as
- * case-insensitive ASCII strings. Packages shall not contain equivalent
- * part names and package implementers shall neither create nor recognize
- * packages with equivalent part names. [M1.12]
- */
- @Override
- public boolean equals(Object otherPartName) {
- if (otherPartName == null
- || !(otherPartName instanceof PackagePartName))
- return false;
- return this.partNameURI.toASCIIString().toLowerCase().equals(
- ((PackagePartName) otherPartName).partNameURI.toASCIIString()
- .toLowerCase());
- }
-
- @Override
- public int hashCode() {
- return this.partNameURI.toASCIIString().toLowerCase().hashCode();
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- /* Getters and setters */
-
- /**
- * Part name property getter.
- *
- * @return This part name URI.
- */
- public URI getURI() {
- return this.partNameURI;
- }
-}
+/* ==================================================================== + 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.net.URI; +import java.net.URISyntaxException; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; + +/** + * An immutable Open Packaging Convention compliant part name. + * + * @author Julien Chable + * + * @see <a href="http://www.ietf.org/rfc/rfc3986.txt">http://www.ietf.org/rfc/rfc3986.txt</a> + */ +public final class PackagePartName implements Comparable<PackagePartName> { + + /** + * Part name stored as an URI. + */ + private URI partNameURI; + + /* + * URI Characters definition (RFC 3986) + */ + + /** + * Reserved characters for sub delimitations. + */ + private static String[] RFC3986_PCHAR_SUB_DELIMS = { "!", "$", "&", "'", + "(", ")", "*", "+", ",", ";", "=" }; + + /** + * Unreserved character (+ ALPHA & DIGIT). + */ + private static String[] RFC3986_PCHAR_UNRESERVED_SUP = { "-", ".", "_", "~" }; + + /** + * Authorized reserved characters for pChar. + */ + private static String[] RFC3986_PCHAR_AUTHORIZED_SUP = { ":", "@" }; + + /** + * Flag to know if this part name is from a relationship part name. + */ + private boolean isRelationship; + + /** + * Constructor. Makes a ValidPartName object from a java.net.URI + * + * @param uri + * The URI to validate and to transform into ValidPartName. + * @param checkConformance + * Flag to specify if the contructor have to validate the OPC + * conformance. Must be always <code>true</code> except for + * special URI like '/' which is needed for internal use by + * OpenXML4J but is not valid. + * @throws InvalidFormatException + * Throw if the specified part name is not conform to Open + * Packaging Convention specifications. + * @see java.net.URI + */ + PackagePartName(URI uri, boolean checkConformance) + throws InvalidFormatException { + if (checkConformance) { + throwExceptionIfInvalidPartUri(uri); + } else { + if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(uri)) { + throw new OpenXML4JRuntimeException( + "OCP conformance must be check for ALL part name except special cases : ['/']"); + } + } + this.partNameURI = uri; + this.isRelationship = isRelationshipPartURI(this.partNameURI); + } + + /** + * Constructor. Makes a ValidPartName object from a String part name. + * + * @param partName + * Part name to valid and to create. + * @param checkConformance + * Flag to specify if the contructor have to validate the OPC + * conformance. Must be always <code>true</code> except for + * special URI like '/' which is needed for internal use by + * OpenXML4J but is not valid. + * @throws InvalidFormatException + * Throw if the specified part name is not conform to Open + * Packaging Convention specifications. + */ + PackagePartName(String partName, boolean checkConformance) + throws InvalidFormatException { + URI partURI; + try { + partURI = new URI(partName); + } catch (URISyntaxException e) { + throw new IllegalArgumentException( + "partName argmument is not a valid OPC part name !"); + } + + if (checkConformance) { + throwExceptionIfInvalidPartUri(partURI); + } else { + if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(partURI)) { + throw new OpenXML4JRuntimeException( + "OCP conformance must be check for ALL part name except special cases : ['/']"); + } + } + this.partNameURI = partURI; + this.isRelationship = isRelationshipPartURI(this.partNameURI); + } + + /** + * Check if the specified part name is a relationship part name. + * + * @param partUri + * The URI to check. + * @return <code>true</code> if this part name respect the relationship + * part naming convention else <code>false</code>. + */ + private boolean isRelationshipPartURI(URI partUri) { + if (partUri == null) + throw new IllegalArgumentException("partUri"); + + return partUri.getPath().matches( + "^.*/" + PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME + "/.*\\" + + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME + + "$"); + } + + /** + * Know if this part name is a relationship part name. + * + * @return <code>true</code> if this part name respect the relationship + * part naming convention else <code>false</code>. + */ + public boolean isRelationshipPartURI() { + return this.isRelationship; + } + + /** + * Throws an exception (of any kind) if the specified part name does not + * follow the Open Packaging Convention specifications naming rules. + * + * @param partUri + * The part name to check. + * @throws Exception + * Throws if the part name is invalid. + */ + private static void throwExceptionIfInvalidPartUri(URI partUri) + throws InvalidFormatException { + if (partUri == null) + throw new IllegalArgumentException("partUri"); + // Check if the part name URI is empty [M1.1] + throwExceptionIfEmptyURI(partUri); + + // Check if the part name URI is absolute + throwExceptionIfAbsoluteUri(partUri); + + // Check if the part name URI starts with a forward slash [M1.4] + throwExceptionIfPartNameNotStartsWithForwardSlashChar(partUri); + + // Check if the part name URI ends with a forward slash [M1.5] + throwExceptionIfPartNameEndsWithForwardSlashChar(partUri); + + // Check if the part name does not have empty segments. [M1.3] + // Check if a segment ends with a dot ('.') character. [M1.9] + throwExceptionIfPartNameHaveInvalidSegments(partUri); + } + + /** + * Throws an exception if the specified URI is empty. [M1.1] + * + * @param partURI + * Part URI to check. + * @throws InvalidFormatException + * If the specified URI is empty. + */ + private static void throwExceptionIfEmptyURI(URI partURI) + throws InvalidFormatException { + if (partURI == null) + throw new IllegalArgumentException("partURI"); + + String uriPath = partURI.getPath(); + if (uriPath.length() == 0 + || ((uriPath.length() == 1) && (uriPath.charAt(0) == PackagingURIHelper.FORWARD_SLASH_CHAR))) + throw new InvalidFormatException( + "A part name shall not be empty [M1.1]: " + + partURI.getPath()); + } + + /** + * Throws an exception if the part name has empty segments. [M1.3] + * + * Throws an exception if a segment any characters other than pchar + * characters. [M1.6] + * + * Throws an exception if a segment contain percent-encoded forward slash + * ('/'), or backward slash ('\') characters. [M1.7] + * + * Throws an exception if a segment contain percent-encoded unreserved + * characters. [M1.8] + * + * Throws an exception if the specified part name's segments end with a dot + * ('.') character. [M1.9] + * + * Throws an exception if a segment doesn't include at least one non-dot + * character. [M1.10] + * + * @param partUri + * The part name to check. + * @throws InvalidFormatException + * if the specified URI contain an empty segments or if one the + * segments contained in the part name, ends with a dot ('.') + * character. + */ + private static void throwExceptionIfPartNameHaveInvalidSegments(URI partUri) + throws InvalidFormatException { + if (partUri == null || "".equals(partUri)) { + throw new IllegalArgumentException("partUri"); + } + + // Split the URI into several part and analyze each + String[] segments = partUri.toASCIIString().split("/"); + if (segments.length <= 1 || !segments[0].equals("")) + throw new InvalidFormatException( + "A part name shall not have empty segments [M1.3]: " + + partUri.getPath()); + + for (int i = 1; i < segments.length; ++i) { + String seg = segments[i]; + if (seg == null || "".equals(seg)) { + throw new InvalidFormatException( + "A part name shall not have empty segments [M1.3]: " + + partUri.getPath()); + } + + if (seg.endsWith(".")) { + throw new InvalidFormatException( + "A segment shall not end with a dot ('.') character [M1.9]: " + + partUri.getPath()); + } + + if ("".equals(seg.replaceAll("\\\\.", ""))) { + // Normally will never been invoked with the previous + // implementation rule [M1.9] + throw new InvalidFormatException( + "A segment shall include at least one non-dot character. [M1.10]: " + + partUri.getPath()); + } + + // Check for rule M1.6, M1.7, M1.8 + checkPCharCompliance(seg); + } + } + + /** + * Throws an exception if a segment any characters other than pchar + * characters. [M1.6] + * + * Throws an exception if a segment contain percent-encoded forward slash + * ('/'), or backward slash ('\') characters. [M1.7] + * + * Throws an exception if a segment contain percent-encoded unreserved + * characters. [M1.8] + * + * @param segment + * The segment to check + */ + private static void checkPCharCompliance(String segment) + throws InvalidFormatException { + boolean errorFlag; + for (int i = 0; i < segment.length(); ++i) { + char c = segment.charAt(i); + errorFlag = true; + + /* Check rule M1.6 */ + + // Check for digit or letter + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') + || (c >= '0' && c <= '9')) { + errorFlag = false; + } else { + // Check "-", ".", "_", "~" + for (int j = 0; j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) { + if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) { + errorFlag = false; + break; + } + } + + // Check ":", "@" + for (int j = 0; errorFlag + && j < RFC3986_PCHAR_AUTHORIZED_SUP.length; ++j) { + if (c == RFC3986_PCHAR_AUTHORIZED_SUP[j].charAt(0)) { + errorFlag = false; + } + } + + // Check "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" + for (int j = 0; errorFlag + && j < RFC3986_PCHAR_SUB_DELIMS.length; ++j) { + if (c == RFC3986_PCHAR_SUB_DELIMS[j].charAt(0)) { + errorFlag = false; + } + } + } + + if (errorFlag && c == '%') { + // We certainly found an encoded character, check for length + // now ( '%' HEXDIGIT HEXDIGIT) + if (((segment.length() - i) < 2)) { + throw new InvalidFormatException("The segment " + segment + + " contain invalid encoded character !"); + } + + // If not percent encoded character error occur then reset the + // flag -> the character is valid + errorFlag = false; + + // Decode the encoded character + char decodedChar = (char) Integer.parseInt(segment.substring( + i + 1, i + 3), 16); + i += 2; + + /* Check rule M1.7 */ + if (decodedChar == '/' || decodedChar == '\\') + throw new InvalidFormatException( + "A segment shall not contain percent-encoded forward slash ('/'), or backward slash ('\') characters. [M1.7]"); + + /* Check rule M1.8 */ + + // Check for unreserved character like define in RFC3986 + if ((decodedChar >= 'A' && decodedChar <= 'Z') + || (decodedChar >= 'a' && decodedChar <= 'z') + || (decodedChar >= '0' && decodedChar <= '9')) + errorFlag = true; + + // Check for unreserved character "-", ".", "_", "~" + for (int j = 0; !errorFlag + && j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) { + if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) { + errorFlag = true; + break; + } + } + if (errorFlag) + throw new InvalidFormatException( + "A segment shall not contain percent-encoded unreserved characters. [M1.8]"); + } + + if (errorFlag) + throw new InvalidFormatException( + "A segment shall not hold any characters other than pchar characters. [M1.6]"); + } + } + + /** + * Throws an exception if the specified part name doesn't start with a + * forward slash character '/'. [M1.4] + * + * @param partUri + * The part name to check. + * @throws InvalidFormatException + * If the specified part name doesn't start with a forward slash + * character '/'. + */ + private static void throwExceptionIfPartNameNotStartsWithForwardSlashChar( + URI partUri) throws InvalidFormatException { + String uriPath = partUri.getPath(); + if (uriPath.length() > 0 + && uriPath.charAt(0) != PackagingURIHelper.FORWARD_SLASH_CHAR) + throw new InvalidFormatException( + "A part name shall start with a forward slash ('/') character [M1.4]: " + + partUri.getPath()); + } + + /** + * Throws an exception if the specified part name ends with a forwar slash + * character '/'. [M1.5] + * + * @param partUri + * The part name to check. + * @throws InvalidFormatException + * If the specified part name ends with a forwar slash character + * '/'. + */ + private static void throwExceptionIfPartNameEndsWithForwardSlashChar( + URI partUri) throws InvalidFormatException { + String uriPath = partUri.getPath(); + if (uriPath.length() > 0 + && uriPath.charAt(uriPath.length() - 1) == PackagingURIHelper.FORWARD_SLASH_CHAR) + throw new InvalidFormatException( + "A part name shall not have a forward slash as the last character [M1.5]: " + + partUri.getPath()); + } + + /** + * Throws an exception if the specified URI is absolute. + * + * @param partUri + * The URI to check. + * @throws InvalidFormatException + * Throws if the specified URI is absolute. + */ + private static void throwExceptionIfAbsoluteUri(URI partUri) + throws InvalidFormatException { + if (partUri.isAbsolute()) + throw new InvalidFormatException("Absolute URI forbidden: " + + partUri); + } + + /** + * Compare two part name following the rule M1.12 : + * + * Part name equivalence is determined by comparing part names as + * case-insensitive ASCII strings. Packages shall not contain equivalent + * part names and package implementers shall neither create nor recognize + * packages with equivalent part names. [M1.12] + */ + public int compareTo(PackagePartName otherPartName) { + if (otherPartName == null) + return -1; + return this.partNameURI.toASCIIString().toLowerCase().compareTo( + otherPartName.partNameURI.toASCIIString().toLowerCase()); + } + + /** + * Retrieves the extension of the part name if any. If there is no extension + * returns an empty String. Example : '/document/content.xml' => 'xml' + * + * @return The extension of the part name. + */ + public String getExtension() { + String fragment = this.partNameURI.getPath(); + if (fragment.length() > 0) { + int i = fragment.lastIndexOf("."); + if (i > -1) + return fragment.substring(i + 1); + } + return ""; + } + + /** + * Get this part name. + * + * @return The name of this part name. + */ + public String getName() { + return this.partNameURI.toASCIIString(); + } + + /** + * Part name equivalence is determined by comparing part names as + * case-insensitive ASCII strings. Packages shall not contain equivalent + * part names and package implementers shall neither create nor recognize + * packages with equivalent part names. [M1.12] + */ + @Override + public boolean equals(Object otherPartName) { + if (otherPartName == null + || !(otherPartName instanceof PackagePartName)) + return false; + return this.partNameURI.toASCIIString().toLowerCase().equals( + ((PackagePartName) otherPartName).partNameURI.toASCIIString() + .toLowerCase()); + } + + @Override + public int hashCode() { + return this.partNameURI.toASCIIString().toLowerCase().hashCode(); + } + + @Override + public String toString() { + return getName(); + } + + /* Getters and setters */ + + /** + * Part name property getter. + * + * @return This part name URI. + */ + public URI getURI() { + return this.partNameURI; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java index e5ecaacc45..e36c025191 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java @@ -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"; +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java index 58f6066aad..b53903df92 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java @@ -1,622 +1,622 @@ -/* ====================================================================
- 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.net.URI;
-import java.net.URISyntaxException;
-
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
-
-/**
- * Helper for part and pack URI.
- *
- * @author Julien Chable, CDubet, Kim Ung
- * @version 0.1
- */
-public final class PackagingURIHelper {
-
- /**
- * Package root URI.
- */
- private static URI packageRootUri;
-
- /**
- * Extension name of a relationship part.
- */
- public static final String RELATIONSHIP_PART_EXTENSION_NAME;
-
- /**
- * Segment name of a relationship part.
- */
- public static final String RELATIONSHIP_PART_SEGMENT_NAME;
-
- /**
- * Segment name of the package properties folder.
- */
- public static final String PACKAGE_PROPERTIES_SEGMENT_NAME;
-
- /**
- * Core package properties art name.
- */
- public static final String PACKAGE_CORE_PROPERTIES_NAME;
-
- /**
- * Forward slash URI separator.
- */
- public static final char FORWARD_SLASH_CHAR;
-
- /**
- * Forward slash URI separator.
- */
- public static final String FORWARD_SLASH_STRING;
-
- /**
- * Package relationships part URI
- */
- public static final URI PACKAGE_RELATIONSHIPS_ROOT_URI;
-
- /**
- * Package relationships part name.
- */
- public static final PackagePartName PACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
-
- /**
- * Core properties part URI.
- */
- public static final URI CORE_PROPERTIES_URI;
-
- /**
- * Core properties partname.
- */
- public static final PackagePartName CORE_PROPERTIES_PART_NAME;
-
- /**
- * Root package URI.
- */
- public static final URI PACKAGE_ROOT_URI;
-
- /**
- * Root package part name.
- */
- public static final PackagePartName PACKAGE_ROOT_PART_NAME;
-
- /* Static initialization */
- static {
- RELATIONSHIP_PART_SEGMENT_NAME = "_rels";
- RELATIONSHIP_PART_EXTENSION_NAME = ".rels";
- FORWARD_SLASH_CHAR = '/';
- FORWARD_SLASH_STRING = "/";
- PACKAGE_PROPERTIES_SEGMENT_NAME = "docProps";
- PACKAGE_CORE_PROPERTIES_NAME = "core.xml";
-
- // Make URI
- URI uriPACKAGE_ROOT_URI = null;
- URI uriPACKAGE_RELATIONSHIPS_ROOT_URI = null;
- URI uriPACKAGE_PROPERTIES_URI = null;
- try {
- uriPACKAGE_ROOT_URI = new URI("/");
- uriPACKAGE_RELATIONSHIPS_ROOT_URI = new URI(FORWARD_SLASH_CHAR
- + RELATIONSHIP_PART_SEGMENT_NAME + FORWARD_SLASH_CHAR
- + RELATIONSHIP_PART_EXTENSION_NAME);
- packageRootUri = new URI("/");
- uriPACKAGE_PROPERTIES_URI = new URI(FORWARD_SLASH_CHAR
- + PACKAGE_PROPERTIES_SEGMENT_NAME + FORWARD_SLASH_CHAR
- + PACKAGE_CORE_PROPERTIES_NAME);
- } catch (URISyntaxException e) {
- // Should never happen in production as all data are fixed
- }
- PACKAGE_ROOT_URI = uriPACKAGE_ROOT_URI;
- PACKAGE_RELATIONSHIPS_ROOT_URI = uriPACKAGE_RELATIONSHIPS_ROOT_URI;
- CORE_PROPERTIES_URI = uriPACKAGE_PROPERTIES_URI;
-
- // Make part name from previous URI
- PackagePartName tmpPACKAGE_ROOT_PART_NAME = null;
- PackagePartName tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = null;
- PackagePartName tmpCORE_PROPERTIES_URI = null;
- try {
- tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = createPartName(PACKAGE_RELATIONSHIPS_ROOT_URI);
- tmpCORE_PROPERTIES_URI = createPartName(CORE_PROPERTIES_URI);
- tmpPACKAGE_ROOT_PART_NAME = new PackagePartName(PACKAGE_ROOT_URI,
- false);
- } catch (InvalidFormatException e) {
- // Should never happen in production as all data are fixed
- }
- PACKAGE_RELATIONSHIPS_ROOT_PART_NAME = tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
- CORE_PROPERTIES_PART_NAME = tmpCORE_PROPERTIES_URI;
- PACKAGE_ROOT_PART_NAME = tmpPACKAGE_ROOT_PART_NAME;
- }
-
- /**
- * Gets the URI for the package root.
- *
- * @return URI of the package root.
- */
- public static URI getPackageRootUri() {
- return packageRootUri;
- }
-
- /**
- * Know if the specified URI is a relationship part name.
- *
- * @param partUri
- * URI to check.
- * @return <i>true</i> if the URI <i>false</i>.
- */
- public static boolean isRelationshipPartURI(URI partUri) {
- if (partUri == null)
- throw new IllegalArgumentException("partUri");
-
- return partUri.getPath().matches(
- ".*" + RELATIONSHIP_PART_SEGMENT_NAME + ".*"
- + RELATIONSHIP_PART_EXTENSION_NAME + "$");
- }
-
- /**
- * Get file name from the specified URI.
- */
- public static String getFilename(URI uri) {
- if (uri != null) {
- String path = uri.getPath();
- int len = path.length();
- int num2 = len;
- while (--num2 >= 0) {
- char ch1 = path.charAt(num2);
- if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR)
- return path.substring(num2 + 1, len);
- }
- }
- return "";
- }
-
- /**
- * Get the file name without the trailing extension.
- */
- public static String getFilenameWithoutExtension(URI uri) {
- String filename = getFilename(uri);
- int dotIndex = filename.lastIndexOf(".");
- if (dotIndex == -1)
- return filename;
- return filename.substring(0, dotIndex);
- }
-
- /**
- * Get the directory path from the specified URI.
- */
- public static URI getPath(URI uri) {
- if (uri != null) {
- String path = uri.getPath();
- int len = path.length();
- int num2 = len;
- while (--num2 >= 0) {
- char ch1 = path.charAt(num2);
- if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) {
- try {
- return new URI(path.substring(0, num2));
- } catch (URISyntaxException e) {
- return null;
- }
- }
- }
- }
- return null;
- }
-
- /**
- * Combine two URIs.
- *
- * @param prefix the prefix URI
- * @param suffix the suffix URI
- *
- * @return the combined URI
- */
- public static URI combine(URI prefix, URI suffix) {
- URI retUri = null;
- try {
- retUri = new URI(combine(prefix.getPath(), suffix.getPath()));
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(
- "Prefix and suffix can't be combine !");
- }
- return retUri;
- }
-
- /**
- * Combine a string URI with a prefix and a suffix.
- */
- public static String combine(String prefix, String suffix) {
- if (!prefix.endsWith("" + FORWARD_SLASH_CHAR)
- && !suffix.startsWith("" + FORWARD_SLASH_CHAR))
- return prefix + FORWARD_SLASH_CHAR + suffix;
- else if ((!prefix.endsWith("" + FORWARD_SLASH_CHAR)
- && suffix.startsWith("" + FORWARD_SLASH_CHAR) || (prefix
- .endsWith("" + FORWARD_SLASH_CHAR) && !suffix.startsWith(""
- + FORWARD_SLASH_CHAR))))
- return prefix + suffix;
- else
- return "";
- }
-
- /**
- * Fully relativize the source part URI against the target part URI.
- *
- * @param sourceURI
- * The source part URI.
- * @param targetURI
- * The target part URI.
- * @return A fully relativize part name URI ('word/media/image1.gif',
- * '/word/document.xml' => 'media/image1.gif') else
- * <code>null</code>.
- */
- public static URI relativizeURI(URI sourceURI, URI targetURI) {
- StringBuilder retVal = new StringBuilder();
- String[] segmentsSource = sourceURI.getPath().split("/", -1);
- String[] segmentsTarget = targetURI.getPath().split("/", -1);
-
- // If the source URI is empty
- if (segmentsSource.length == 0) {
- throw new IllegalArgumentException(
- "Can't relativize an empty source URI !");
- }
-
- // If target URI is empty
- if (segmentsTarget.length == 0) {
- throw new IllegalArgumentException(
- "Can't relativize an empty target URI !");
- }
-
- // If the source is the root, then the relativized
- // form must actually be an absolute URI
- if(sourceURI.toString().equals("/")) {
- return targetURI;
- }
-
-
- // Relativize the source URI against the target URI.
- // First up, figure out how many steps along we can go
- // and still have them be the same
- int segmentsTheSame = 0;
- for (int i = 0; i < segmentsSource.length && i < segmentsTarget.length; i++) {
- if (segmentsSource[i].equals(segmentsTarget[i])) {
- // Match so far, good
- segmentsTheSame++;
- } else {
- break;
- }
- }
-
- // If we didn't have a good match or at least except a first empty element
- if ((segmentsTheSame == 0 || segmentsTheSame == 1) &&
- segmentsSource[0].equals("") && segmentsTarget[0].equals("")) {
- for (int i = 0; i < segmentsSource.length - 2; i++) {
- retVal.append("../");
- }
- for (int i = 0; i < segmentsTarget.length; i++) {
- if (segmentsTarget[i].equals(""))
- continue;
- retVal.append(segmentsTarget[i]);
- if (i != segmentsTarget.length - 1)
- retVal.append("/");
- }
-
- try {
- return new URI(retVal.toString());
- } catch (Exception e) {
- System.err.println(e);
- return null;
- }
- }
-
- // Special case for where the two are the same
- if (segmentsTheSame == segmentsSource.length
- && segmentsTheSame == segmentsTarget.length) {
- retVal.append("");
- } else {
- // Matched for so long, but no more
-
- // Do we need to go up a directory or two from
- // the source to get here?
- // (If it's all the way up, then don't bother!)
- if (segmentsTheSame == 1) {
- retVal.append("/");
- } else {
- for (int j = segmentsTheSame; j < segmentsSource.length - 1; j++) {
- retVal.append("../");
- }
- }
-
- // Now go from here on down
- for (int j = segmentsTheSame; j < segmentsTarget.length; j++) {
- if (retVal.length() > 0
- && retVal.charAt(retVal.length() - 1) != '/') {
- retVal.append("/");
- }
- retVal.append(segmentsTarget[j]);
- }
- }
-
- try {
- return new URI(retVal.toString());
- } catch (Exception e) {
- System.err.println(e);
- return null;
- }
- }
-
- /**
- * Resolve a source uri against a target.
- *
- * @param sourcePartUri
- * The source URI.
- * @param targetUri
- * The target URI.
- * @return The resolved URI.
- */
- public static URI resolvePartUri(URI sourcePartUri, URI targetUri) {
- if (sourcePartUri == null || sourcePartUri.isAbsolute()) {
- throw new IllegalArgumentException("sourcePartUri invalid - "
- + sourcePartUri);
- }
-
- if (targetUri == null || targetUri.isAbsolute()) {
- throw new IllegalArgumentException("targetUri invalid - "
- + targetUri);
- }
-
- return sourcePartUri.resolve(targetUri);
- }
-
- /**
- * Get URI from a string path.
- */
- public static URI getURIFromPath(String path) {
- URI retUri = null;
- try {
- retUri = new URI(path);
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException("path");
- }
- return retUri;
- }
-
- /**
- * Get the source part URI from a specified relationships part.
- *
- * @param relationshipPartUri
- * The relationship part use to retrieve the source part.
- * @return The source part URI from the specified relationships part.
- */
- public static URI getSourcePartUriFromRelationshipPartUri(
- URI relationshipPartUri) {
- if (relationshipPartUri == null)
- throw new IllegalArgumentException(
- "Must not be null");
-
- if (!isRelationshipPartURI(relationshipPartUri))
- throw new IllegalArgumentException(
- "Must be a relationship part");
-
- if (relationshipPartUri.compareTo(PACKAGE_RELATIONSHIPS_ROOT_URI) == 0)
- return PACKAGE_ROOT_URI;
-
- String filename = relationshipPartUri.getPath();
- String filenameWithoutExtension = getFilenameWithoutExtension(relationshipPartUri);
- filename = filename
- .substring(0, ((filename.length() - filenameWithoutExtension
- .length()) - RELATIONSHIP_PART_EXTENSION_NAME.length()));
- filename = filename.substring(0, filename.length()
- - RELATIONSHIP_PART_SEGMENT_NAME.length() - 1);
- filename = combine(filename, filenameWithoutExtension);
- return getURIFromPath(filename);
- }
-
- /**
- * Create an OPC compliant part name by throwing an exception if the URI is
- * not valid.
- *
- * @param partUri
- * The part name URI to validate.
- * @return A valid part name object, else <code>null</code>.
- * @throws InvalidFormatException
- * Throws if the specified URI is not OPC compliant.
- */
- public static PackagePartName createPartName(URI partUri)
- throws InvalidFormatException {
- if (partUri == null)
- throw new IllegalArgumentException("partName");
-
- return new PackagePartName(partUri, true);
- }
-
- /**
- * Create an OPC compliant part name.
- *
- * @param partName
- * The part name to validate.
- * @return The correspondant part name if valid, else <code>null</code>.
- * @throws InvalidFormatException
- * Throws if the specified part name is not OPC compliant.
- * @see #createPartName(URI)
- */
- public static PackagePartName createPartName(String partName)
- throws InvalidFormatException {
- URI partNameURI;
- try {
- partNameURI = new URI(partName);
- } catch (URISyntaxException e) {
- throw new InvalidFormatException(e.getMessage());
- }
- return createPartName(partNameURI);
- }
-
- /**
- * Create an OPC compliant part name by resolving it using a base part.
- *
- * @param partName
- * The part name to validate.
- * @param relativePart
- * The relative base part.
- * @return The correspondant part name if valid, else <code>null</code>.
- * @throws InvalidFormatException
- * Throws if the specified part name is not OPC compliant.
- * @see #createPartName(URI)
- */
- public static PackagePartName createPartName(String partName,
- PackagePart relativePart) throws InvalidFormatException {
- URI newPartNameURI;
- try {
- newPartNameURI = resolvePartUri(
- relativePart.getPartName().getURI(), new URI(partName));
- } catch (URISyntaxException e) {
- throw new InvalidFormatException(e.getMessage());
- }
- return createPartName(newPartNameURI);
- }
-
- /**
- * Create an OPC compliant part name by resolving it using a base part.
- *
- * @param partName
- * The part name URI to validate.
- * @param relativePart
- * The relative base part.
- * @return The correspondant part name if valid, else <code>null</code>.
- * @throws InvalidFormatException
- * Throws if the specified part name is not OPC compliant.
- * @see #createPartName(URI)
- */
- public static PackagePartName createPartName(URI partName,
- PackagePart relativePart) throws InvalidFormatException {
- URI newPartNameURI = resolvePartUri(
- relativePart.getPartName().getURI(), partName);
- return createPartName(newPartNameURI);
- }
-
- /**
- * Validate a part URI by returning a boolean.
- * ([M1.1],[M1.3],[M1.4],[M1.5],[M1.6])
- *
- * (OPC Specifications 8.1.1 Part names) :
- *
- * Part Name Syntax
- *
- * The part name grammar is defined as follows:
- *
- * <i>part_name = 1*( "/" segment )
- *
- * segment = 1*( pchar )</i>
- *
- *
- * (pchar is defined in RFC 3986)
- *
- * @param partUri
- * The URI to validate.
- * @return <b>true</b> if the URI is valid to the OPC Specifications, else
- * <b>false</b>
- *
- * @see #createPartName(URI)
- */
- public static boolean isValidPartName(URI partUri) {
- if (partUri == null)
- throw new IllegalArgumentException("partUri");
-
- try {
- createPartName(partUri);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- /**
- * Decode a URI by converting all percent encoded character into a String
- * character.
- *
- * @param uri
- * The URI to decode.
- * @return The specified URI in a String with converted percent encoded
- * characters.
- */
- public static String decodeURI(URI uri) {
- StringBuffer retVal = new StringBuffer();
- String uriStr = uri.toASCIIString();
- char c;
- for (int i = 0; i < uriStr.length(); ++i) {
- c = uriStr.charAt(i);
- if (c == '%') {
- // We certainly found an encoded character, check for length
- // now ( '%' HEXDIGIT HEXDIGIT)
- if (((uriStr.length() - i) < 2)) {
- throw new IllegalArgumentException("The uri " + uriStr
- + " contain invalid encoded character !");
- }
-
- // Decode the encoded character
- char decodedChar = (char) Integer.parseInt(uriStr.substring(
- i + 1, i + 3), 16);
- retVal.append(decodedChar);
- i += 2;
- continue;
- }
- retVal.append(c);
- }
- return retVal.toString();
- }
-
- /**
- * Build a part name where the relationship should be stored ((ex
- * /word/document.xml -> /word/_rels/document.xml.rels)
- *
- * @param partName
- * Source part URI
- * @return the full path (as URI) of the relation file
- * @throws InvalidOperationException
- * Throws if the specified URI is a relationshp part.
- */
- public static PackagePartName getRelationshipPartName(
- PackagePartName partName) {
- if (partName == null)
- throw new IllegalArgumentException("partName");
-
- if (PackagingURIHelper.PACKAGE_ROOT_URI.getPath() == partName.getURI()
- .getPath())
- return PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
-
- if (partName.isRelationshipPartURI())
- throw new InvalidOperationException("Can't be a relationship part");
-
- String fullPath = partName.getURI().getPath();
- String filename = getFilename(partName.getURI());
- fullPath = fullPath.substring(0, fullPath.length() - filename.length());
- fullPath = combine(fullPath,
- PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME);
- fullPath = combine(fullPath, filename);
- fullPath = fullPath
- + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME;
-
- PackagePartName retPartName;
- try {
- retPartName = createPartName(fullPath);
- } catch (InvalidFormatException e) {
- // Should never happen in production as all data are fixed but in
- // case of return null:
- return null;
- }
- return retPartName;
- }
-}
+/* ==================================================================== + 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.net.URI; +import java.net.URISyntaxException; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.exceptions.InvalidOperationException; + +/** + * Helper for part and pack URI. + * + * @author Julien Chable, CDubet, Kim Ung + * @version 0.1 + */ +public final class PackagingURIHelper { + + /** + * Package root URI. + */ + private static URI packageRootUri; + + /** + * Extension name of a relationship part. + */ + public static final String RELATIONSHIP_PART_EXTENSION_NAME; + + /** + * Segment name of a relationship part. + */ + public static final String RELATIONSHIP_PART_SEGMENT_NAME; + + /** + * Segment name of the package properties folder. + */ + public static final String PACKAGE_PROPERTIES_SEGMENT_NAME; + + /** + * Core package properties art name. + */ + public static final String PACKAGE_CORE_PROPERTIES_NAME; + + /** + * Forward slash URI separator. + */ + public static final char FORWARD_SLASH_CHAR; + + /** + * Forward slash URI separator. + */ + public static final String FORWARD_SLASH_STRING; + + /** + * Package relationships part URI + */ + public static final URI PACKAGE_RELATIONSHIPS_ROOT_URI; + + /** + * Package relationships part name. + */ + public static final PackagePartName PACKAGE_RELATIONSHIPS_ROOT_PART_NAME; + + /** + * Core properties part URI. + */ + public static final URI CORE_PROPERTIES_URI; + + /** + * Core properties partname. + */ + public static final PackagePartName CORE_PROPERTIES_PART_NAME; + + /** + * Root package URI. + */ + public static final URI PACKAGE_ROOT_URI; + + /** + * Root package part name. + */ + public static final PackagePartName PACKAGE_ROOT_PART_NAME; + + /* Static initialization */ + static { + RELATIONSHIP_PART_SEGMENT_NAME = "_rels"; + RELATIONSHIP_PART_EXTENSION_NAME = ".rels"; + FORWARD_SLASH_CHAR = '/'; + FORWARD_SLASH_STRING = "/"; + PACKAGE_PROPERTIES_SEGMENT_NAME = "docProps"; + PACKAGE_CORE_PROPERTIES_NAME = "core.xml"; + + // Make URI + URI uriPACKAGE_ROOT_URI = null; + URI uriPACKAGE_RELATIONSHIPS_ROOT_URI = null; + URI uriPACKAGE_PROPERTIES_URI = null; + try { + uriPACKAGE_ROOT_URI = new URI("/"); + uriPACKAGE_RELATIONSHIPS_ROOT_URI = new URI(FORWARD_SLASH_CHAR + + RELATIONSHIP_PART_SEGMENT_NAME + FORWARD_SLASH_CHAR + + RELATIONSHIP_PART_EXTENSION_NAME); + packageRootUri = new URI("/"); + uriPACKAGE_PROPERTIES_URI = new URI(FORWARD_SLASH_CHAR + + PACKAGE_PROPERTIES_SEGMENT_NAME + FORWARD_SLASH_CHAR + + PACKAGE_CORE_PROPERTIES_NAME); + } catch (URISyntaxException e) { + // Should never happen in production as all data are fixed + } + PACKAGE_ROOT_URI = uriPACKAGE_ROOT_URI; + PACKAGE_RELATIONSHIPS_ROOT_URI = uriPACKAGE_RELATIONSHIPS_ROOT_URI; + CORE_PROPERTIES_URI = uriPACKAGE_PROPERTIES_URI; + + // Make part name from previous URI + PackagePartName tmpPACKAGE_ROOT_PART_NAME = null; + PackagePartName tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = null; + PackagePartName tmpCORE_PROPERTIES_URI = null; + try { + tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = createPartName(PACKAGE_RELATIONSHIPS_ROOT_URI); + tmpCORE_PROPERTIES_URI = createPartName(CORE_PROPERTIES_URI); + tmpPACKAGE_ROOT_PART_NAME = new PackagePartName(PACKAGE_ROOT_URI, + false); + } catch (InvalidFormatException e) { + // Should never happen in production as all data are fixed + } + PACKAGE_RELATIONSHIPS_ROOT_PART_NAME = tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME; + CORE_PROPERTIES_PART_NAME = tmpCORE_PROPERTIES_URI; + PACKAGE_ROOT_PART_NAME = tmpPACKAGE_ROOT_PART_NAME; + } + + /** + * Gets the URI for the package root. + * + * @return URI of the package root. + */ + public static URI getPackageRootUri() { + return packageRootUri; + } + + /** + * Know if the specified URI is a relationship part name. + * + * @param partUri + * URI to check. + * @return <i>true</i> if the URI <i>false</i>. + */ + public static boolean isRelationshipPartURI(URI partUri) { + if (partUri == null) + throw new IllegalArgumentException("partUri"); + + return partUri.getPath().matches( + ".*" + RELATIONSHIP_PART_SEGMENT_NAME + ".*" + + RELATIONSHIP_PART_EXTENSION_NAME + "$"); + } + + /** + * Get file name from the specified URI. + */ + public static String getFilename(URI uri) { + if (uri != null) { + String path = uri.getPath(); + int len = path.length(); + int num2 = len; + while (--num2 >= 0) { + char ch1 = path.charAt(num2); + if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) + return path.substring(num2 + 1, len); + } + } + return ""; + } + + /** + * Get the file name without the trailing extension. + */ + public static String getFilenameWithoutExtension(URI uri) { + String filename = getFilename(uri); + int dotIndex = filename.lastIndexOf("."); + if (dotIndex == -1) + return filename; + return filename.substring(0, dotIndex); + } + + /** + * Get the directory path from the specified URI. + */ + public static URI getPath(URI uri) { + if (uri != null) { + String path = uri.getPath(); + int len = path.length(); + int num2 = len; + while (--num2 >= 0) { + char ch1 = path.charAt(num2); + if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) { + try { + return new URI(path.substring(0, num2)); + } catch (URISyntaxException e) { + return null; + } + } + } + } + return null; + } + + /** + * Combine two URIs. + * + * @param prefix the prefix URI + * @param suffix the suffix URI + * + * @return the combined URI + */ + public static URI combine(URI prefix, URI suffix) { + URI retUri = null; + try { + retUri = new URI(combine(prefix.getPath(), suffix.getPath())); + } catch (URISyntaxException e) { + throw new IllegalArgumentException( + "Prefix and suffix can't be combine !"); + } + return retUri; + } + + /** + * Combine a string URI with a prefix and a suffix. + */ + public static String combine(String prefix, String suffix) { + if (!prefix.endsWith("" + FORWARD_SLASH_CHAR) + && !suffix.startsWith("" + FORWARD_SLASH_CHAR)) + return prefix + FORWARD_SLASH_CHAR + suffix; + else if ((!prefix.endsWith("" + FORWARD_SLASH_CHAR) + && suffix.startsWith("" + FORWARD_SLASH_CHAR) || (prefix + .endsWith("" + FORWARD_SLASH_CHAR) && !suffix.startsWith("" + + FORWARD_SLASH_CHAR)))) + return prefix + suffix; + else + return ""; + } + + /** + * Fully relativize the source part URI against the target part URI. + * + * @param sourceURI + * The source part URI. + * @param targetURI + * The target part URI. + * @return A fully relativize part name URI ('word/media/image1.gif', + * '/word/document.xml' => 'media/image1.gif') else + * <code>null</code>. + */ + public static URI relativizeURI(URI sourceURI, URI targetURI) { + StringBuilder retVal = new StringBuilder(); + String[] segmentsSource = sourceURI.getPath().split("/", -1); + String[] segmentsTarget = targetURI.getPath().split("/", -1); + + // If the source URI is empty + if (segmentsSource.length == 0) { + throw new IllegalArgumentException( + "Can't relativize an empty source URI !"); + } + + // If target URI is empty + if (segmentsTarget.length == 0) { + throw new IllegalArgumentException( + "Can't relativize an empty target URI !"); + } + + // If the source is the root, then the relativized + // form must actually be an absolute URI + if(sourceURI.toString().equals("/")) { + return targetURI; + } + + + // Relativize the source URI against the target URI. + // First up, figure out how many steps along we can go + // and still have them be the same + int segmentsTheSame = 0; + for (int i = 0; i < segmentsSource.length && i < segmentsTarget.length; i++) { + if (segmentsSource[i].equals(segmentsTarget[i])) { + // Match so far, good + segmentsTheSame++; + } else { + break; + } + } + + // If we didn't have a good match or at least except a first empty element + if ((segmentsTheSame == 0 || segmentsTheSame == 1) && + segmentsSource[0].equals("") && segmentsTarget[0].equals("")) { + for (int i = 0; i < segmentsSource.length - 2; i++) { + retVal.append("../"); + } + for (int i = 0; i < segmentsTarget.length; i++) { + if (segmentsTarget[i].equals("")) + continue; + retVal.append(segmentsTarget[i]); + if (i != segmentsTarget.length - 1) + retVal.append("/"); + } + + try { + return new URI(retVal.toString()); + } catch (Exception e) { + System.err.println(e); + return null; + } + } + + // Special case for where the two are the same + if (segmentsTheSame == segmentsSource.length + && segmentsTheSame == segmentsTarget.length) { + retVal.append(""); + } else { + // Matched for so long, but no more + + // Do we need to go up a directory or two from + // the source to get here? + // (If it's all the way up, then don't bother!) + if (segmentsTheSame == 1) { + retVal.append("/"); + } else { + for (int j = segmentsTheSame; j < segmentsSource.length - 1; j++) { + retVal.append("../"); + } + } + + // Now go from here on down + for (int j = segmentsTheSame; j < segmentsTarget.length; j++) { + if (retVal.length() > 0 + && retVal.charAt(retVal.length() - 1) != '/') { + retVal.append("/"); + } + retVal.append(segmentsTarget[j]); + } + } + + try { + return new URI(retVal.toString()); + } catch (Exception e) { + System.err.println(e); + return null; + } + } + + /** + * Resolve a source uri against a target. + * + * @param sourcePartUri + * The source URI. + * @param targetUri + * The target URI. + * @return The resolved URI. + */ + public static URI resolvePartUri(URI sourcePartUri, URI targetUri) { + if (sourcePartUri == null || sourcePartUri.isAbsolute()) { + throw new IllegalArgumentException("sourcePartUri invalid - " + + sourcePartUri); + } + + if (targetUri == null || targetUri.isAbsolute()) { + throw new IllegalArgumentException("targetUri invalid - " + + targetUri); + } + + return sourcePartUri.resolve(targetUri); + } + + /** + * Get URI from a string path. + */ + public static URI getURIFromPath(String path) { + URI retUri = null; + try { + retUri = new URI(path); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("path"); + } + return retUri; + } + + /** + * Get the source part URI from a specified relationships part. + * + * @param relationshipPartUri + * The relationship part use to retrieve the source part. + * @return The source part URI from the specified relationships part. + */ + public static URI getSourcePartUriFromRelationshipPartUri( + URI relationshipPartUri) { + if (relationshipPartUri == null) + throw new IllegalArgumentException( + "Must not be null"); + + if (!isRelationshipPartURI(relationshipPartUri)) + throw new IllegalArgumentException( + "Must be a relationship part"); + + if (relationshipPartUri.compareTo(PACKAGE_RELATIONSHIPS_ROOT_URI) == 0) + return PACKAGE_ROOT_URI; + + String filename = relationshipPartUri.getPath(); + String filenameWithoutExtension = getFilenameWithoutExtension(relationshipPartUri); + filename = filename + .substring(0, ((filename.length() - filenameWithoutExtension + .length()) - RELATIONSHIP_PART_EXTENSION_NAME.length())); + filename = filename.substring(0, filename.length() + - RELATIONSHIP_PART_SEGMENT_NAME.length() - 1); + filename = combine(filename, filenameWithoutExtension); + return getURIFromPath(filename); + } + + /** + * Create an OPC compliant part name by throwing an exception if the URI is + * not valid. + * + * @param partUri + * The part name URI to validate. + * @return A valid part name object, else <code>null</code>. + * @throws InvalidFormatException + * Throws if the specified URI is not OPC compliant. + */ + public static PackagePartName createPartName(URI partUri) + throws InvalidFormatException { + if (partUri == null) + throw new IllegalArgumentException("partName"); + + return new PackagePartName(partUri, true); + } + + /** + * Create an OPC compliant part name. + * + * @param partName + * The part name to validate. + * @return The correspondant part name if valid, else <code>null</code>. + * @throws InvalidFormatException + * Throws if the specified part name is not OPC compliant. + * @see #createPartName(URI) + */ + public static PackagePartName createPartName(String partName) + throws InvalidFormatException { + URI partNameURI; + try { + partNameURI = new URI(partName); + } catch (URISyntaxException e) { + throw new InvalidFormatException(e.getMessage()); + } + return createPartName(partNameURI); + } + + /** + * Create an OPC compliant part name by resolving it using a base part. + * + * @param partName + * The part name to validate. + * @param relativePart + * The relative base part. + * @return The correspondant part name if valid, else <code>null</code>. + * @throws InvalidFormatException + * Throws if the specified part name is not OPC compliant. + * @see #createPartName(URI) + */ + public static PackagePartName createPartName(String partName, + PackagePart relativePart) throws InvalidFormatException { + URI newPartNameURI; + try { + newPartNameURI = resolvePartUri( + relativePart.getPartName().getURI(), new URI(partName)); + } catch (URISyntaxException e) { + throw new InvalidFormatException(e.getMessage()); + } + return createPartName(newPartNameURI); + } + + /** + * Create an OPC compliant part name by resolving it using a base part. + * + * @param partName + * The part name URI to validate. + * @param relativePart + * The relative base part. + * @return The correspondant part name if valid, else <code>null</code>. + * @throws InvalidFormatException + * Throws if the specified part name is not OPC compliant. + * @see #createPartName(URI) + */ + public static PackagePartName createPartName(URI partName, + PackagePart relativePart) throws InvalidFormatException { + URI newPartNameURI = resolvePartUri( + relativePart.getPartName().getURI(), partName); + return createPartName(newPartNameURI); + } + + /** + * Validate a part URI by returning a boolean. + * ([M1.1],[M1.3],[M1.4],[M1.5],[M1.6]) + * + * (OPC Specifications 8.1.1 Part names) : + * + * Part Name Syntax + * + * The part name grammar is defined as follows: + * + * <i>part_name = 1*( "/" segment ) + * + * segment = 1*( pchar )</i> + * + * + * (pchar is defined in RFC 3986) + * + * @param partUri + * The URI to validate. + * @return <b>true</b> if the URI is valid to the OPC Specifications, else + * <b>false</b> + * + * @see #createPartName(URI) + */ + public static boolean isValidPartName(URI partUri) { + if (partUri == null) + throw new IllegalArgumentException("partUri"); + + try { + createPartName(partUri); + return true; + } catch (Exception e) { + return false; + } + } + + /** + * Decode a URI by converting all percent encoded character into a String + * character. + * + * @param uri + * The URI to decode. + * @return The specified URI in a String with converted percent encoded + * characters. + */ + public static String decodeURI(URI uri) { + StringBuffer retVal = new StringBuffer(); + String uriStr = uri.toASCIIString(); + char c; + for (int i = 0; i < uriStr.length(); ++i) { + c = uriStr.charAt(i); + if (c == '%') { + // We certainly found an encoded character, check for length + // now ( '%' HEXDIGIT HEXDIGIT) + if (((uriStr.length() - i) < 2)) { + throw new IllegalArgumentException("The uri " + uriStr + + " contain invalid encoded character !"); + } + + // Decode the encoded character + char decodedChar = (char) Integer.parseInt(uriStr.substring( + i + 1, i + 3), 16); + retVal.append(decodedChar); + i += 2; + continue; + } + retVal.append(c); + } + return retVal.toString(); + } + + /** + * Build a part name where the relationship should be stored ((ex + * /word/document.xml -> /word/_rels/document.xml.rels) + * + * @param partName + * Source part URI + * @return the full path (as URI) of the relation file + * @throws InvalidOperationException + * Throws if the specified URI is a relationshp part. + */ + public static PackagePartName getRelationshipPartName( + PackagePartName partName) { + if (partName == null) + throw new IllegalArgumentException("partName"); + + if (PackagingURIHelper.PACKAGE_ROOT_URI.getPath() == partName.getURI() + .getPath()) + return PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME; + + if (partName.isRelationshipPartURI()) + throw new InvalidOperationException("Can't be a relationship part"); + + String fullPath = partName.getURI().getPath(); + String filename = getFilename(partName.getURI()); + fullPath = fullPath.substring(0, fullPath.length() - filename.length()); + fullPath = combine(fullPath, + PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME); + fullPath = combine(fullPath, filename); + fullPath = fullPath + + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME; + + PackagePartName retPartName; + try { + retPartName = createPartName(fullPath); + } catch (InvalidFormatException e) { + // Should never happen in production as all data are fixed but in + // case of return null: + return null; + } + return retPartName; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java index 1d55c7bb7f..a02264ea68 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java index 12a5a55ffa..834c2ad66e 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java @@ -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 +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java index f3e9a578ce..6e676cc9b2 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java index 5f40940b47..ecf45af549 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java @@ -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 §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, \§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 §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, \§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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java index ad31157372..cc41e43520 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java @@ -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 ""; + } + +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java index debe3d185e..ed0bc6a74a 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePartOutputStream.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java index 70bbcae6b6..e30d71783a 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java @@ -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; +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java index 0b17cb8926..e5487a6381 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java @@ -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; +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java index 10b2339ec4..ab867ad250 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java @@ -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; + } + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java index 8138cda8be..8cd2f7d245 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java index 438cc5dcbb..1ad4d26b71 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java @@ -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()); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java index 39e8fa3f3d..07123b22dc 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPackagePropertiesMarshaller.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java index c226ba5a42..b59a78b74c 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java @@ -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 + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalCertificatePart.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalCertificatePart.java index bce033e3e3..19ba500f2e 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalCertificatePart.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalCertificatePart.java @@ -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; + } + +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalSignatureOriginPart.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalSignatureOriginPart.java index 718e78b765..b6c1a8ac87 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalSignatureOriginPart.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/signature/DigitalSignatureOriginPart.java @@ -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 { + +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java index fc03b022ff..a86f56d0af 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java @@ -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()); + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignature.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignature.java index 8922641ce6..c7a9b8f7ea 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignature.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignature.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignatureManager.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignatureManager.java index 0e5136d3ac..64007f6f00 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignatureManager.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/signature/PackageDigitalSignatureManager.java @@ -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 { + +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java b/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java index 9bcea2e3ce..8c1a24c863 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java b/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java index 30a800e531..af1d55a960 100755 --- a/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java +++ b/src/ooxml/java/org/apache/poi/xssf/dev/XSSFDump.java @@ -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); + + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java b/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java index 10a4b4755e..4b2fc3ca53 100755 --- a/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java +++ b/src/ooxml/java/org/apache/poi/xssf/dev/XSSFSave.java @@ -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(); + } + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java index f640f408df..a804176fcd 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java @@ -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 ); + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java index d02ee82d02..5032395394 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java @@ -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()); + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java index b23429fa01..b6a17fe53e 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java @@ -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; + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java index 92f0d1d73c..f7cf9d5a75 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java @@ -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(); + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java index 24943ba834..ffdc684f5b 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java index ef2bdf89b3..5264281f00 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java @@ -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; + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java index 4736ecbc4a..ab0ef2b443 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java @@ -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); + } + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java index e58b58377b..ef548e7b97 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java @@ -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(); + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java index cd6c2208df..4734a26fa5 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java @@ -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); + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java index ac6b1268ba..de2c22cdc2 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java @@ -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"); + } + +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java index d5dd19c1ba..3667c8cbb7 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java @@ -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"); + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java index a708a759fd..027f83bf2e 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java @@ -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); + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java index 26fdad839c..9facfe8f28 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java @@ -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; + } + +} diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java index fd0b635654..3b2a90baec 100755 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Borders.java @@ -1,626 +1,626 @@ -/* ====================================================================
- 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.HashMap;
-import java.util.Map;
-
-/**
- * Specifies all types of borders which can be specified for WordprocessingML
- * objects which have a border. Borders can be separated into two types:
- * <ul>
- * <li> Line borders: which specify a pattern to be used when drawing a line around the
- * specified object.
- * </li>
- * <li> Art borders: which specify a repeated image to be used
- * when drawing a border around the specified object. Line borders may be
- * specified on any object which allows a border, however, art borders may only
- * be used as a border at the page level - the borders under the pgBorders
- * element
- *</li>
- * </ul>
- * @author Gisella Bronzetti
- */
-public enum Borders {
-
- NIL(1),
-
- NONE(2),
-
- /**
- * Specifies a line border consisting of a single line around the parent
- * object.
- */
- SINGLE(3),
-
- THICK(4),
-
- DOUBLE(5),
-
- DOTTED(6),
-
- DASHED(7),
-
- DOT_DASH(8),
-
- DOT_DOT_DASH(9),
-
- TRIPLE(10),
-
- THIN_THICK_SMALL_GAP(11),
-
- THICK_THIN_SMALL_GAP(12),
-
- THIN_THICK_THIN_SMALL_GAP(13),
-
- THIN_THICK_MEDIUM_GAP(14),
-
- THICK_THIN_MEDIUM_GAP(15),
-
- THIN_THICK_THIN_MEDIUM_GAP(16),
-
- THIN_THICK_LARGE_GAP(17),
-
- THICK_THIN_LARGE_GAP(18),
-
- THIN_THICK_THIN_LARGE_GAP(19),
-
- WAVE(20),
-
- DOUBLE_WAVE(21),
-
- DASH_SMALL_GAP(22),
-
- DASH_DOT_STROKED(23),
-
- THREE_D_EMBOSS(24),
-
- THREE_D_ENGRAVE(25),
-
- OUTSET(26),
-
- INSET(27),
-
- /**
- * Specifies an art border consisting of a repeated image of an apple
- */
- APPLES(28),
-
- /**
- * Specifies an art border consisting of a repeated image of a shell pattern
- */
- ARCHED_SCALLOPS(29),
-
- /**
- * Specifies an art border consisting of a repeated image of a baby pacifier
- */
- BABY_PACIFIER(30),
-
- /**
- * Specifies an art border consisting of a repeated image of a baby rattle
- */
- BABY_RATTLE(31),
-
- /**
- * Specifies an art border consisting of a repeated image of a set of
- * balloons
- */
- BALLOONS_3_COLORS(32),
-
- /**
- * Specifies an art border consisting of a repeated image of a hot air
- * balloon
- */
- BALLOONS_HOT_AIR(33),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background.
- */
- BASIC_BLACK_DASHES(34),
-
- /**
- * Specifies an art border consisting of a repeating image of a black dot on
- * a white background.
- */
- BASIC_BLACK_DOTS(35),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background
- */
- BASIC_BLACK_SQUARES(36),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background.
- */
- BASIC_THIN_LINES(37),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background.
- */
- BASIC_WHITE_DASHES(38),
-
- /**
- * Specifies an art border consisting of a repeating image of a white dot on
- * a black background.
- */
- BASIC_WHITE_DOTS(39),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background.
- */
- BASIC_WHITE_SQUARES(40),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background.
- */
- BASIC_WIDE_INLINE(41),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background
- */
- BASIC_WIDE_MIDLINE(42),
-
- /**
- * Specifies an art border consisting of a repeating image of a black and
- * white background
- */
- BASIC_WIDE_OUTLINE(43),
-
- /**
- * Specifies an art border consisting of a repeated image of bats
- */
- BATS(44),
-
- /**
- * Specifies an art border consisting of repeating images of birds
- */
- BIRDS(45),
-
- /**
- * Specifies an art border consisting of a repeated image of birds flying
- */
- BIRDS_FLIGHT(46),
-
- /**
- * Specifies an art border consisting of a repeated image of a cabin
- */
- CABINS(47),
-
- /**
- * Specifies an art border consisting of a repeated image of a piece of cake
- */
- CAKE_SLICE(48),
-
- /**
- * Specifies an art border consisting of a repeated image of candy corn
- */
- CANDY_CORN(49),
-
- /**
- * Specifies an art border consisting of a repeated image of a knot work
- * pattern
- */
- CELTIC_KNOTWORK(50),
-
- /**
- * Specifies an art border consisting of a banner.
- * <p>
- * If the border is on the left or right, no border is displayed.
- * </p>
- */
- CERTIFICATE_BANNER(51),
-
- /**
- * Specifies an art border consisting of a repeating image of a chain link
- * pattern.
- */
- CHAIN_LINK(52),
-
- /**
- * Specifies an art border consisting of a repeated image of a champagne
- * bottle
- */
- CHAMPAGNE_BOTTLE(53),
-
- /**
- * Specifies an art border consisting of repeating images of a compass
- */
- CHECKED_BAR_BLACK(54),
-
- /**
- * Specifies an art border consisting of a repeating image of a colored
- * pattern.
- */
- CHECKED_BAR_COLOR(55),
-
- /**
- * Specifies an art border consisting of a repeated image of a checkerboard
- */
- CHECKERED(56),
-
- /**
- * Specifies an art border consisting of a repeated image of a Christmas
- * tree
- */
- CHRISTMAS_TREE(57),
-
- /**
- * Specifies an art border consisting of repeating images of lines and
- * circles
- */
- CIRCLES_LINES(58),
-
- /**
- * Specifies an art border consisting of a repeated image of a rectangular
- * pattern
- */
- CIRCLES_RECTANGLES(59),
-
- /**
- * Specifies an art border consisting of a repeated image of a wave
- */
- CLASSICAL_WAVE(60),
-
- /**
- * Specifies an art border consisting of a repeated image of a clock
- */
- CLOCKS(61),
-
- /**
- * Specifies an art border consisting of repeating images of a compass
- */
- COMPASS(62),
-
- /**
- * Specifies an art border consisting of a repeated image of confetti
- */
- CONFETTI(63),
-
- /**
- * Specifies an art border consisting of a repeated image of confetti
- */
- CONFETTI_GRAYS(64),
-
- /**
- * Specifies an art border consisting of a repeated image of confetti
- */
- CONFETTI_OUTLINE(65),
-
- /**
- * Specifies an art border consisting of a repeated image of confetti
- * streamers
- */
- CONFETTI_STREAMERS(66),
-
- /**
- * Specifies an art border consisting of a repeated image of confetti
- */
- CONFETTI_WHITE(67),
-
- /**
- * Specifies an art border consisting of a repeated image
- */
- CORNER_TRIANGLES(68),
-
- /**
- * Specifies an art border consisting of a dashed line
- */
- COUPON_CUTOUT_DASHES(69),
-
- /**
- * Specifies an art border consisting of a dotted line
- */
- COUPON_CUTOUT_DOTS(70),
-
- /**
- * Specifies an art border consisting of a repeated image of a maze-like
- * pattern
- */
- CRAZY_MAZE(71),
-
- /**
- * Specifies an art border consisting of a repeated image of a butterfly
- */
- CREATURES_BUTTERFLY(72),
-
- /**
- * Specifies an art border consisting of a repeated image of a fish
- */
- CREATURES_FISH(73),
-
- /**
- * Specifies an art border consisting of repeating images of insects.
- */
- CREATURES_INSECTS(74),
-
- /**
- * Specifies an art border consisting of a repeated image of a ladybug
- */
- CREATURES_LADY_BUG(75),
-
- /**
- * Specifies an art border consisting of repeating images of a cross-stitch
- * pattern
- */
- CROSS_STITCH(76),
-
- /**
- * Specifies an art border consisting of a repeated image of Cupid
- */
- CUP(77),
-
- DECO_ARCH(78),
-
- DECO_ARCH_COLOR(79),
-
- DECO_BLOCKS(80),
-
- DIAMONDS_GRAY(81),
-
- DOUBLE_D(82),
-
- DOUBLE_DIAMONDS(83),
-
- EARTH_1(84),
-
- EARTH_2(85),
-
- ECLIPSING_SQUARES_1(86),
-
- ECLIPSING_SQUARES_2(87),
-
- EGGS_BLACK(88),
-
- FANS(89),
-
- FILM(90),
-
- FIRECRACKERS(91),
-
- FLOWERS_BLOCK_PRINT(92),
-
- FLOWERS_DAISIES(93),
-
- FLOWERS_MODERN_1(94),
-
- FLOWERS_MODERN_2(95),
-
- FLOWERS_PANSY(96),
-
- FLOWERS_RED_ROSE(97),
-
- FLOWERS_ROSES(98),
-
- FLOWERS_TEACUP(99),
-
- FLOWERS_TINY(100),
-
- GEMS(101),
-
- GINGERBREAD_MAN(102),
-
- GRADIENT(103),
-
- HANDMADE_1(104),
-
- HANDMADE_2(105),
-
- HEART_BALLOON(106),
-
- HEART_GRAY(107),
-
- HEARTS(108),
-
- HEEBIE_JEEBIES(109),
-
- HOLLY(110),
-
- HOUSE_FUNKY(111),
-
- HYPNOTIC(112),
-
- ICE_CREAM_CONES(113),
-
- LIGHT_BULB(114),
-
- LIGHTNING_1(115),
-
- LIGHTNING_2(116),
-
- MAP_PINS(117),
-
- MAPLE_LEAF(118),
-
- MAPLE_MUFFINS(119),
-
- MARQUEE(120),
-
- MARQUEE_TOOTHED(121),
-
- MOONS(122),
-
- MOSAIC(123),
-
- MUSIC_NOTES(124),
-
- NORTHWEST(125),
-
- OVALS(126),
-
- PACKAGES(127),
-
- PALMS_BLACK(128),
-
- PALMS_COLOR(129),
-
- PAPER_CLIPS(130),
-
- PAPYRUS(131),
-
- PARTY_FAVOR(132),
-
- PARTY_GLASS(133),
-
- PENCILS(134),
-
- PEOPLE(135),
-
- PEOPLE_WAVING(136),
-
- PEOPLE_HATS(137),
-
- POINSETTIAS(138),
-
- POSTAGE_STAMP(139),
-
- PUMPKIN_1(140),
-
- PUSH_PIN_NOTE_2(141),
-
- PUSH_PIN_NOTE_1(142),
-
- PYRAMIDS(143),
-
- PYRAMIDS_ABOVE(144),
-
- QUADRANTS(145),
-
- RINGS(146),
-
- SAFARI(147),
-
- SAWTOOTH(148),
-
- SAWTOOTH_GRAY(149),
-
- SCARED_CAT(150),
-
- SEATTLE(151),
-
- SHADOWED_SQUARES(152),
-
- SHARKS_TEETH(153),
-
- SHOREBIRD_TRACKS(154),
-
- SKYROCKET(155),
-
- SNOWFLAKE_FANCY(156),
-
- SNOWFLAKES(157),
-
- SOMBRERO(158),
-
- SOUTHWEST(159),
-
- STARS(160),
-
- STARS_TOP(161),
-
- STARS_3_D(162),
-
- STARS_BLACK(163),
-
- STARS_SHADOWED(164),
-
- SUN(165),
-
- SWIRLIGIG(166),
-
- TORN_PAPER(167),
-
- TORN_PAPER_BLACK(168),
-
- TREES(169),
-
- TRIANGLE_PARTY(170),
-
- TRIANGLES(171),
-
- TRIBAL_1(172),
-
- TRIBAL_2(173),
-
- TRIBAL_3(174),
-
- TRIBAL_4(175),
-
- TRIBAL_5(176),
-
- TRIBAL_6(177),
-
- TWISTED_LINES_1(178),
-
- TWISTED_LINES_2(179),
-
- VINE(180),
-
- WAVELINE(181),
-
- WEAVING_ANGLES(182),
-
- WEAVING_BRAID(183),
-
- WEAVING_RIBBON(184),
-
- WEAVING_STRIPS(185),
-
- WHITE_FLOWERS(186),
-
- WOODWORK(187),
-
- X_ILLUSIONS(188),
-
- ZANY_TRIANGLES(189),
-
- ZIG_ZAG(190),
-
- ZIG_ZAG_STITCH(191);
-
- private final int value;
-
- private Borders(int val) {
- value = val;
- }
-
- public int getValue() {
- return value;
- }
-
- private static Map<Integer, Borders> imap = new HashMap<Integer, Borders>();
- static {
- for (Borders p : values()) {
- imap.put(p.getValue(), p);
- }
- }
-
- public static Borders valueOf(int type) {
- Borders pBorder = imap.get(type);
- if (pBorder == null)
- throw new IllegalArgumentException("Unknown paragraph border: "
- + type);
- return pBorder;
- }
-
-}
+/* ==================================================================== + 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.HashMap; +import java.util.Map; + +/** + * Specifies all types of borders which can be specified for WordprocessingML + * objects which have a border. Borders can be separated into two types: + * <ul> + * <li> Line borders: which specify a pattern to be used when drawing a line around the + * specified object. + * </li> + * <li> Art borders: which specify a repeated image to be used + * when drawing a border around the specified object. Line borders may be + * specified on any object which allows a border, however, art borders may only + * be used as a border at the page level - the borders under the pgBorders + * element + *</li> + * </ul> + * @author Gisella Bronzetti + */ +public enum Borders { + + NIL(1), + + NONE(2), + + /** + * Specifies a line border consisting of a single line around the parent + * object. + */ + SINGLE(3), + + THICK(4), + + DOUBLE(5), + + DOTTED(6), + + DASHED(7), + + DOT_DASH(8), + + DOT_DOT_DASH(9), + + TRIPLE(10), + + THIN_THICK_SMALL_GAP(11), + + THICK_THIN_SMALL_GAP(12), + + THIN_THICK_THIN_SMALL_GAP(13), + + THIN_THICK_MEDIUM_GAP(14), + + THICK_THIN_MEDIUM_GAP(15), + + THIN_THICK_THIN_MEDIUM_GAP(16), + + THIN_THICK_LARGE_GAP(17), + + THICK_THIN_LARGE_GAP(18), + + THIN_THICK_THIN_LARGE_GAP(19), + + WAVE(20), + + DOUBLE_WAVE(21), + + DASH_SMALL_GAP(22), + + DASH_DOT_STROKED(23), + + THREE_D_EMBOSS(24), + + THREE_D_ENGRAVE(25), + + OUTSET(26), + + INSET(27), + + /** + * Specifies an art border consisting of a repeated image of an apple + */ + APPLES(28), + + /** + * Specifies an art border consisting of a repeated image of a shell pattern + */ + ARCHED_SCALLOPS(29), + + /** + * Specifies an art border consisting of a repeated image of a baby pacifier + */ + BABY_PACIFIER(30), + + /** + * Specifies an art border consisting of a repeated image of a baby rattle + */ + BABY_RATTLE(31), + + /** + * Specifies an art border consisting of a repeated image of a set of + * balloons + */ + BALLOONS_3_COLORS(32), + + /** + * Specifies an art border consisting of a repeated image of a hot air + * balloon + */ + BALLOONS_HOT_AIR(33), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background. + */ + BASIC_BLACK_DASHES(34), + + /** + * Specifies an art border consisting of a repeating image of a black dot on + * a white background. + */ + BASIC_BLACK_DOTS(35), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background + */ + BASIC_BLACK_SQUARES(36), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background. + */ + BASIC_THIN_LINES(37), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background. + */ + BASIC_WHITE_DASHES(38), + + /** + * Specifies an art border consisting of a repeating image of a white dot on + * a black background. + */ + BASIC_WHITE_DOTS(39), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background. + */ + BASIC_WHITE_SQUARES(40), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background. + */ + BASIC_WIDE_INLINE(41), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background + */ + BASIC_WIDE_MIDLINE(42), + + /** + * Specifies an art border consisting of a repeating image of a black and + * white background + */ + BASIC_WIDE_OUTLINE(43), + + /** + * Specifies an art border consisting of a repeated image of bats + */ + BATS(44), + + /** + * Specifies an art border consisting of repeating images of birds + */ + BIRDS(45), + + /** + * Specifies an art border consisting of a repeated image of birds flying + */ + BIRDS_FLIGHT(46), + + /** + * Specifies an art border consisting of a repeated image of a cabin + */ + CABINS(47), + + /** + * Specifies an art border consisting of a repeated image of a piece of cake + */ + CAKE_SLICE(48), + + /** + * Specifies an art border consisting of a repeated image of candy corn + */ + CANDY_CORN(49), + + /** + * Specifies an art border consisting of a repeated image of a knot work + * pattern + */ + CELTIC_KNOTWORK(50), + + /** + * Specifies an art border consisting of a banner. + * <p> + * If the border is on the left or right, no border is displayed. + * </p> + */ + CERTIFICATE_BANNER(51), + + /** + * Specifies an art border consisting of a repeating image of a chain link + * pattern. + */ + CHAIN_LINK(52), + + /** + * Specifies an art border consisting of a repeated image of a champagne + * bottle + */ + CHAMPAGNE_BOTTLE(53), + + /** + * Specifies an art border consisting of repeating images of a compass + */ + CHECKED_BAR_BLACK(54), + + /** + * Specifies an art border consisting of a repeating image of a colored + * pattern. + */ + CHECKED_BAR_COLOR(55), + + /** + * Specifies an art border consisting of a repeated image of a checkerboard + */ + CHECKERED(56), + + /** + * Specifies an art border consisting of a repeated image of a Christmas + * tree + */ + CHRISTMAS_TREE(57), + + /** + * Specifies an art border consisting of repeating images of lines and + * circles + */ + CIRCLES_LINES(58), + + /** + * Specifies an art border consisting of a repeated image of a rectangular + * pattern + */ + CIRCLES_RECTANGLES(59), + + /** + * Specifies an art border consisting of a repeated image of a wave + */ + CLASSICAL_WAVE(60), + + /** + * Specifies an art border consisting of a repeated image of a clock + */ + CLOCKS(61), + + /** + * Specifies an art border consisting of repeating images of a compass + */ + COMPASS(62), + + /** + * Specifies an art border consisting of a repeated image of confetti + */ + CONFETTI(63), + + /** + * Specifies an art border consisting of a repeated image of confetti + */ + CONFETTI_GRAYS(64), + + /** + * Specifies an art border consisting of a repeated image of confetti + */ + CONFETTI_OUTLINE(65), + + /** + * Specifies an art border consisting of a repeated image of confetti + * streamers + */ + CONFETTI_STREAMERS(66), + + /** + * Specifies an art border consisting of a repeated image of confetti + */ + CONFETTI_WHITE(67), + + /** + * Specifies an art border consisting of a repeated image + */ + CORNER_TRIANGLES(68), + + /** + * Specifies an art border consisting of a dashed line + */ + COUPON_CUTOUT_DASHES(69), + + /** + * Specifies an art border consisting of a dotted line + */ + COUPON_CUTOUT_DOTS(70), + + /** + * Specifies an art border consisting of a repeated image of a maze-like + * pattern + */ + CRAZY_MAZE(71), + + /** + * Specifies an art border consisting of a repeated image of a butterfly + */ + CREATURES_BUTTERFLY(72), + + /** + * Specifies an art border consisting of a repeated image of a fish + */ + CREATURES_FISH(73), + + /** + * Specifies an art border consisting of repeating images of insects. + */ + CREATURES_INSECTS(74), + + /** + * Specifies an art border consisting of a repeated image of a ladybug + */ + CREATURES_LADY_BUG(75), + + /** + * Specifies an art border consisting of repeating images of a cross-stitch + * pattern + */ + CROSS_STITCH(76), + + /** + * Specifies an art border consisting of a repeated image of Cupid + */ + CUP(77), + + DECO_ARCH(78), + + DECO_ARCH_COLOR(79), + + DECO_BLOCKS(80), + + DIAMONDS_GRAY(81), + + DOUBLE_D(82), + + DOUBLE_DIAMONDS(83), + + EARTH_1(84), + + EARTH_2(85), + + ECLIPSING_SQUARES_1(86), + + ECLIPSING_SQUARES_2(87), + + EGGS_BLACK(88), + + FANS(89), + + FILM(90), + + FIRECRACKERS(91), + + FLOWERS_BLOCK_PRINT(92), + + FLOWERS_DAISIES(93), + + FLOWERS_MODERN_1(94), + + FLOWERS_MODERN_2(95), + + FLOWERS_PANSY(96), + + FLOWERS_RED_ROSE(97), + + FLOWERS_ROSES(98), + + FLOWERS_TEACUP(99), + + FLOWERS_TINY(100), + + GEMS(101), + + GINGERBREAD_MAN(102), + + GRADIENT(103), + + HANDMADE_1(104), + + HANDMADE_2(105), + + HEART_BALLOON(106), + + HEART_GRAY(107), + + HEARTS(108), + + HEEBIE_JEEBIES(109), + + HOLLY(110), + + HOUSE_FUNKY(111), + + HYPNOTIC(112), + + ICE_CREAM_CONES(113), + + LIGHT_BULB(114), + + LIGHTNING_1(115), + + LIGHTNING_2(116), + + MAP_PINS(117), + + MAPLE_LEAF(118), + + MAPLE_MUFFINS(119), + + MARQUEE(120), + + MARQUEE_TOOTHED(121), + + MOONS(122), + + MOSAIC(123), + + MUSIC_NOTES(124), + + NORTHWEST(125), + + OVALS(126), + + PACKAGES(127), + + PALMS_BLACK(128), + + PALMS_COLOR(129), + + PAPER_CLIPS(130), + + PAPYRUS(131), + + PARTY_FAVOR(132), + + PARTY_GLASS(133), + + PENCILS(134), + + PEOPLE(135), + + PEOPLE_WAVING(136), + + PEOPLE_HATS(137), + + POINSETTIAS(138), + + POSTAGE_STAMP(139), + + PUMPKIN_1(140), + + PUSH_PIN_NOTE_2(141), + + PUSH_PIN_NOTE_1(142), + + PYRAMIDS(143), + + PYRAMIDS_ABOVE(144), + + QUADRANTS(145), + + RINGS(146), + + SAFARI(147), + + SAWTOOTH(148), + + SAWTOOTH_GRAY(149), + + SCARED_CAT(150), + + SEATTLE(151), + + SHADOWED_SQUARES(152), + + SHARKS_TEETH(153), + + SHOREBIRD_TRACKS(154), + + SKYROCKET(155), + + SNOWFLAKE_FANCY(156), + + SNOWFLAKES(157), + + SOMBRERO(158), + + SOUTHWEST(159), + + STARS(160), + + STARS_TOP(161), + + STARS_3_D(162), + + STARS_BLACK(163), + + STARS_SHADOWED(164), + + SUN(165), + + SWIRLIGIG(166), + + TORN_PAPER(167), + + TORN_PAPER_BLACK(168), + + TREES(169), + + TRIANGLE_PARTY(170), + + TRIANGLES(171), + + TRIBAL_1(172), + + TRIBAL_2(173), + + TRIBAL_3(174), + + TRIBAL_4(175), + + TRIBAL_5(176), + + TRIBAL_6(177), + + TWISTED_LINES_1(178), + + TWISTED_LINES_2(179), + + VINE(180), + + WAVELINE(181), + + WEAVING_ANGLES(182), + + WEAVING_BRAID(183), + + WEAVING_RIBBON(184), + + WEAVING_STRIPS(185), + + WHITE_FLOWERS(186), + + WOODWORK(187), + + X_ILLUSIONS(188), + + ZANY_TRIANGLES(189), + + ZIG_ZAG(190), + + ZIG_ZAG_STITCH(191); + + private final int value; + + private Borders(int val) { + value = val; + } + + public int getValue() { + return value; + } + + private static Map<Integer, Borders> imap = new HashMap<Integer, Borders>(); + static { + for (Borders p : values()) { + imap.put(new Integer(p.getValue()), p); + } + } + + public static Borders valueOf(int type) { + Borders pBorder = imap.get(new Integer(type)); + if (pBorder == null) { + throw new IllegalArgumentException("Unknown paragraph border: " + type); + } + return pBorder; + } +} diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java index 6c8aad1c7f..503aeca8e3 100755 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java @@ -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; + } + +} diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java index 04bf13d113..02b18d9a2e 100755 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java @@ -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); + } + } + +} diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java index b58db4a75f..5532ee299f 100755 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java @@ -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); + } + +} |