git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@776607 13f79535-47bb-0310-9956-ffa450edef68pull/1/head
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 | |||
} |
@@ -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 | |||
} |
@@ -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"; | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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"; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 ""; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 { | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 { | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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 ); | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |